Python cant handle exceptions from zipfile.BadZipFile - python

Need to handle if a zip file is corrupt, so it just pass this file and can go on to the next.
In the code example underneath Im trying to catch the exception, so I can pass it. But my script is failing when the zipfile is corrupt*, and give me the "normal" traceback errors* istead of printing "my error", but is running ok if the zipfile is ok.
This i a minimalistic example of the code I'm dealing with.
path = "path to zipfile"
from zipfile import ZipFile
with ZipFile(path) as zf:
try:
print "zipfile is OK"
except BadZipfile:
print "Does not work "
pass
part of the traceback is telling me: raise BadZipfile, "File is not a zip file"

You need to put your context manager inside the try-except block:
try:
with ZipFile(path) as zf:
print "zipfile is OK"
except BadZipfile:
print "Does not work "
The error is raised by ZipFile so placing it outside means no handler can be found for the raised exception. In addition make sure you appropriately import BadZipFile from zipfile.

Related

Is it possible to continue when you hit a BadZipFile?

This zip-file contains 130.000 images.
Is it possible to continue when you run into a BadZipFile?
I mean ignore the bad image and move on to the next.
import zipfile
with zipfile.ZipFile("/content/train.zip", 'r') as zip_ref:
zip_ref.extractall("/content/train/")
The error:
BadZipFile: Bad CRC-32 for file 'calvary-andrea-mantegna.jpg
I want something like this to work.
import zipfile
from zipfile import BadZipfile
try:
with zipfile.ZipFile("/content/train.zip", 'r') as zip_ref:
zip_ref.extractall("/content/train/")
except BadZipfile:
continue
But i know i cant use a continue in a try-except.
Is there a way to solve this?
You can extract files one by one. This may not work, depending what corrupted the file. For instance, if a block of the file was lost somewhere in the middle of the file, all unzips after that will fail.
import zipfile
try:
with zipfile.ZipFile("/content/train.zip", 'r') as zip_ref:
for info in zip_ref.infolist():
try:
zip_ref.extract(info, path="/content/train/")
except zipfile.BadZipFile as e:
print(f"{e} - offset {info.header_offset}")
except zipfile.BadZipFile as e:
print(f"could not read zipfile: {e}")

exception stop read files python

I'm trying to control exceptions when reading files, but I have a problem. I'm new to Python, and I am not yet able to control how I can catch an exception and still continue reading text from the files I am accessing. This is my code:
import errno
import sys
class Read:
#FIXME do immutables this 2 const
ROUTE = "d:\Profiles\user\Desktop\\"
EXT = ".txt"
def setFileReaded(self, fileToRead):
content = ""
try:
infile = open(self.ROUTE+fileToRead+self.EXT)
except FileNotFoundError as error:
if error.errno == errno.ENOENT:
print ("File not found, please check the name and try again")
else:
raise
sys.exit()
with infile:
content = infile.read()
infile.close()
return content
And from another class I tell it:
read = Read()
print(read.setFileReaded("verbs"))
print(read.setFileReaded("object"))
print(read.setFileReaded("sites"))
print(read.setFileReaded("texts"))
Buy only print this one:
turn on
connect
plug
File not found, please check the name and try again
And no continue with the next files. How can the program still reading all files?
It's a little difficult to understand exactly what you're asking here, but I'll try and provide some pointers.
sys.exit() will terminate the Python script gracefully. In your code, this is called when the FileNotFoundError exception is caught. Nothing further will be ran after this, because your script will terminate. So none of the other files will be read.
Another thing to point out is that you close the file after reading it, which is not needed when you open it like this:
with open('myfile.txt') as f:
content = f.read()
The file will be closed automatically after the with block.

Python file does not exist exception

I am trying to open a file and read from it and if the file is not there, I catch the exception and throw an error to stderr. The code that I have:
for x in l:
try:
f = open(x,'r')
except IOError:
print >> sys.stderr, "No such file" , x
but nothing is being printed to stderr, does open create a new file if the file name doesn't exist or is the problem somewhere else?
Try this:
from __future__ import print_statement
import sys
if os.path.exists(x):
with open(x, 'r') as f:
# Do Stuff with file
else:
print("No such file '{}'".format(x), file=sys.stderr)
The goal here is to be as clear as possible about what is happening. We first check if the file exists by calling os.path.exists(x). This returns True or False, allowing us to simply use it in an if statement.
From there you can open the file for reading, or handle exiting as you like. Using the Python3 style print function allows you to explicitly declare where your output goes, in this case to stderr.
You have the os.path.exists function:
import os.path
os.path.exists(file_path)
returns bool
It works for me. Why can't you make use of os.path.exists()
for x in l:
if not os.path.exists(x):
print >> sys.stderr , "No such file", x

Detecting for invalid file inputs, Python

I have an assignment to write a Python script which "detects whether the file is readable or not".
I am stuck as to which exceptions I should run. Let's say the input file is intended to be a text file, with extension *.txt
What is the exception I should raise? I suspect there should be multiple. At the moment, I have:
with open('example_file.txt") as textfile:
if not textfile.lower().endswith('.txt'):
raise argparse.ArgumentTypeError(
'Not a text file! Argument filename must be of type *.txt')
return textfile
However, that only checks the file extension. What else could I possibly check? What is the standard for file I/O in Python?
To check whether the file exists:
import os.path
if os.path.exists('example_file.txt'):
print('it exists!')
Beyond this, successfully opening the file will demonstrate readability. The built-in open raises an IOError exception if it fails. Failure can occur for more than one reason, so we must check whether it failed due to readability:
import errno
try:
textfile = open('example_file.txt', 'r')
textfile.close()
print("file is readable")
except IOError as e:
if e.errno == errno.EACCES:
print("file exists, but isn't readable")
elif e.errno == errno.ENOENT:
print("files isn't readable because it isn't there")
The relevant section of the docs on file permissions. Note that the use of os.access to check readability before calling open is discouraged.

Stop an operation without stopping the module in python

Well, I have made a module that allows you to copy a file to a directory easier. Now, I also have some "try's" and "except's" in there to make sure it doesn't fail in the big messy way and doesn't close the terminal, but I also want it to display different error messages when a wrong string or variable is put in, and end the module, but not the...if I may say, Terminal running it, so I did this:
def copy():
import shutil
import os
try:
cpy = input("CMD>>> Name of file(with extension): ")
open(cpy, "r")
except:
print("ERROR>>> 02x00 No such file")
try:
dri = input("CMD>>> Name of Directory: ")
os.chdir(dri)
os.chdir("..")
except:
print("ERROR>>> 03x00 No such directory")
try:
shutil.copy(cpy, dri)
except:
print("ERROR>>> 04x00 Command Failure")
Problem is that it doesn't end the module if there is no file or directory, only at the finish.
You may be thinking that when an exception is raised, Python just stops what it's doing, but that's not quite true. The except: block actually catches the exception raised, and is supposed to handle it. After an except: block finishes, Python will continue on executing the rest of the code in the file.
In your case, I'd put a return after each print(...). That way, after Python prints out an error message, it will also return from the copy() function rather than continuing to ask for more input.
If you did want to make the module exit on error...
Here's how you'd do it.
def copy():
import shutil
import os
import sys
try:
cpy = input("CMD>>> Name of file(with extension): ")
open(cpy, "r")
except:
sys.exit("ERROR>>> 02x00 No such file")
try:
dri = input("CMD>>> Name of Directory: ")
os.chdir(dri)
os.chdir("..")
except:
sys.exit("ERROR>>> 03x00 No such directory")
try:
shutil.copy(cpy, dri)
except:
sys.exit("ERROR>>> 04x00 Command Failure")
sys.exit(0) (for success) and sys.exit(1) (for failure) are usually used but, since you want to output the error, the above example will output the error string to stderr.
Here's a link for more info on sys.exit().

Categories