keep having permission error while creating a hdf5 file - python

I have the following segment of code to create a hdf5 file, and have used "with" statement to ensure the file is correctly closed. However, I still keep having the error message as follows.
filename = 'E30.hdf5'
try:
with h5py.File(filename, 'w-') as f:
print('---')
except:
os.remove(filename)
f = h5py.File(filename, 'w-')
However, I still keep having the error message as follows. In the working directory, there may already have an existing file with the name of 'E30.hdf5'. But does it really matter? I tried to delete it from windows directly. However, the windows does not allow me to delete it saying it is being opened.
---------------------------------------------------------------------------
OSError Traceback (most recent call last)
<ipython-input-6-e8ccfbc1b5d2> in vid_to_hdf(En, start, end, chunk)
9 try:
---> 10 with h5py.File(filename, 'w-') as f:
11 print('---')
~\AppData\Local\Continuum\anaconda3\envs\fastai-py37\lib\site-packages\h5py\_hl\files.py in __init__(self, name, mode, driver, libver, userblock_size, swmr, rdcc_nslots, rdcc_nbytes, rdcc_w0, track_order, **kwds)
407 fapl, fcpl=make_fcpl(track_order=track_order),
--> 408 swmr=swmr)
409
~\AppData\Local\Continuum\anaconda3\envs\fastai-py37\lib\site-packages\h5py\_hl\files.py in make_fid(name, mode, userblock_size, fapl, fcpl, swmr)
176 elif mode in ['w-', 'x']:
--> 177 fid = h5f.create(name, h5f.ACC_EXCL, fapl=fapl, fcpl=fcpl)
178 elif mode == 'w':
h5py\_objects.pyx in h5py._objects.with_phil.wrapper()
h5py\_objects.pyx in h5py._objects.with_phil.wrapper()
h5py\h5f.pyx in h5py.h5f.create()
OSError: Unable to create file (unable to open file: name = 'E30.hdf5', errno = 17, error message = 'File exists', flags = 15, o_flags = 502)
During handling of the above exception, another exception occurred:
PermissionError Traceback (most recent call last)
<timed eval> in <module>
<ipython-input-6-e8ccfbc1b5d2> in vid_to_hdf(En, start, end, chunk)
11 print('---')
12 except:
---> 13 os.remove(filename)
14 f = h5py.File(filename, 'w-')
15 # Create dataset within file
PermissionError: [WinError 32] The process cannot access the file because it is being used by another process: 'E30.hdf5'

You are running into multiple issues at once.
First, let's start with the h5py.File() access_mode flag.
w- : Create file, fail if exists (avoids accidentally overwriting an existing file)
w : Create file, truncate if exists (means it overwrites an existing file)
r+ : Read/write, file must exist (use to open an existing file to write data).
In your logic below, your try:/except: pattern will execute the try: statement if E30.hdf5 does not exist. It will execute the except: statement if E30.hdf5 exists.
This is complicated by different h5py.File() methods is each branch. Your try: branch uses the with h5py.File() as f: method. So, when your code executes this logic, the file will close cleanly at the end (without a f.close() statement).
HOWEVER, your except: branch uses f=h5py.File(). So, when your code executes this logic, you need a f.close() statement to ensure closure at the end.
This is the scenario I think you are experiencing:
I assume E30.hdf5 does not exist the first time you run your code.
So, the first time you run, you go through the try: branch and the file is closed cleanly at the end.
The next time you run the code, E30.hdf5 exists, so, you go through the except: branch. As a result, the file is NOT closed at the end of the process, and another process cannot access it (Python or the OS).
Coding suggestions:
Your except: block has the same behavior mode=w. The code below behaves the same, and will always close the file when the process completes. Also, it is more readable (IMHO). Note: both methods delete E30.hdf5 if it exists.
filename = 'E30.hdf5'
with h5py.File(filename, 'w') as f: # use mode=w
print('---')
Make this change if there is a burning need to keep the try:/except: pattern: (it's useful to use try:/except: for access modes w- and r+ WITHOUT the os.remove(filename).)
filename = 'E30.hdf5'
try:
with h5py.File(filename, 'w-') as f:
print('---')
except:
os.remove(filename)
with h5py.File(filename, 'w-') as f:
print('+++')

Related

File has zero lines in else block of python try except code

I have a simple python code to open the .csv file and check for exceptions.
The file exists in my current folder and it has more than 2 lines of data.
But the for loop in the else part is not executing.. because I'm getting zero lines to count.
# Base class for defining your own user-defined exceptions.
class Error(Exception):
'''Base class for other exceptions'''
pass
# own exception class as a subclass of error
class EmptyFileError(Error):
pass
# raise error
try:
# open the file (no error check for this example).
thefile = open('people.csv')
# count the number of lines in file.
file_content = thefile.readlines()
line_count = len(file_content)
# If there is fewer than 2 lines, raise exception.
if line_count < 2:
raise EmptyFileError
# Handles missing file error.
except FileNotFoundError:
print('\n There is no people.csv file here')
# Handles my custom error for too few rows.
except EmptyFileError:
print('\nYour people.csv does not have enough stuff')
# Handles all other Exceptions
except Exceptions as e:
# Show the error
print('\n\nFailed: The error was '+str(e))
# Close the file
thefile.close()
else:
print(thefile.name)
# file must be open if we got here
for one_line in file_content:
print(list(one_line.split(',')))
thefile.close()
print('Success')
I was able to see the output of the file name and success message from the else part but not the for loop part. There were no exceptions occurred and so the file was never closed before else part.
What could be the problem?
Solved with the help of #Ralf answer.
You already consumed all the lines of the file by calling thefile.readlines(); when you start the loop for one_line in thefile: there are no more lines to read, so the loop never gets executed.
Possible solution: use a variable to hold the file contents.
line_list = thefile.readlines()
line_count = len(line_list)
and the iterate over that:
for one_line in line_list:
Here are some related questions with more info:
Read multiple times lines of the same file Python
Why can't I call read() twice on an open file?

Delete a file after reading

In my code, user uploads file which is saved on server and read using the server path. I'm trying to delete the file from that path after I'm done reading it. But it gives me following error instead:
An error occurred while reading file. [WinError 32] The process cannot access the file because it is being used by another process
I'm reading file using with, and I've tried f.close() and also f.closed but its the same error every time.
This is my code:
f = open(filePath)
with f:
line = f.readline().strip()
tempLst = line.split(fileSeparator)
if(len(lstHeader) != len(tempLst)):
headerErrorMsg = "invalid headers"
hjsonObj["Line No."] = 1
hjsonObj["Error Detail"] = headerErrorMsg
data['lstErrorData'].append(hjsonObj)
data["status"] = True
f.closed
return data
f.closed
after this code I call the remove function:
os.remove(filePath)
Edit: using with open(filePath) as f: and then trying to remove the file gives the same error.
Instead of:
f.closed
You need to say:
f.close()
closed is just a boolean property on the file object to indicate if the file is actually closed.
close() is method on the file object that actually closes the file.
Side note: attempting a file delete after closing a file handle is not 100% reliable. The file might still be getting scanned by the virus scanner or indexer. Or some other system hook is holding on to the file reference, etc... If the delete fails, wait a second and try again.
Use below code:
import os
os.startfile('your_file.py')
To delete after completion:
os.remove('your_file.py')
This
import os
path = 'path/to/file'
with open(path) as f:
for l in f:
print l,
os.remove(path)
should work, with statement will automatically close the file after the nested block of code
if it fails, File could be in use by some external factor. you can use Redo pattern.
while True:
try:
os.remove(path)
break
except:
time.sleep(1)
There is probably an application that is opening the file; check and close the application before executing your code:
os.remove(file_path)
Delete files that are not used by another application.

Raising a FileNotFoundError

I have a function that takes a source file containing times (a csv file), reads it, then sorts the lines in order and writes them in a destination file. However, if the source csv file does not exist, I need to raise a FileNotFoundError. I've raised exceptions before, for example, if a parameter wasn't an integer I had to raise ChangeParameterError by using:
class ChangeParameterError(Exception):
pass
and then raising that in my function.
For my problem, my function is as follows:
def times(src,dst):
s = open(src,'r')
d = open(dst,'w')
lines = s.readlines()
s.close()
lines.sort()
for i in lines:
print((str(i).strip()), file = d)
d.close()
Any help is appreciated!
If the specified file is not found, the FileNotFoundError will be raised automatically by the open call when trying to open the file.
The exception is automatically raised by python. But you may need to wrap your open with a try-except to catch the exception without breaking your code:
try:
s = open(src,'r')
except FileNotFoundError:
print('file not found')

Why do I get "Pickle - EOFError: Ran out of input" reading an empty file?

I am getting an interesting error while trying to use Unpickler.load(), here is the source code:
open(target, 'a').close()
scores = {};
with open(target, "rb") as file:
unpickler = pickle.Unpickler(file);
scores = unpickler.load();
if not isinstance(scores, dict):
scores = {};
Here is the traceback:
Traceback (most recent call last):
File "G:\python\pendu\user_test.py", line 3, in <module>:
save_user_points("Magix", 30);
File "G:\python\pendu\user.py", line 22, in save_user_points:
scores = unpickler.load();
EOFError: Ran out of input
The file I am trying to read is empty.
How can I avoid getting this error, and get an empty variable instead?
Most of the answers here have dealt with how to mange EOFError exceptions, which is really handy if you're unsure about whether the pickled object is empty or not.
However, if you're surprised that the pickle file is empty, it could be because you opened the filename through 'wb' or some other mode that could have over-written the file.
for example:
filename = 'cd.pkl'
with open(filename, 'wb') as f:
classification_dict = pickle.load(f)
This will over-write the pickled file. You might have done this by mistake before using:
...
open(filename, 'rb') as f:
And then got the EOFError because the previous block of code over-wrote the cd.pkl file.
When working in Jupyter, or in the console (Spyder) I usually write a wrapper over the reading/writing code, and call the wrapper subsequently. This avoids common read-write mistakes, and saves a bit of time if you're going to be reading the same file multiple times through your travails
I would check that the file is not empty first:
import os
scores = {} # scores is an empty dict already
if os.path.getsize(target) > 0:
with open(target, "rb") as f:
unpickler = pickle.Unpickler(f)
# if file is not empty scores will be equal
# to the value unpickled
scores = unpickler.load()
Also open(target, 'a').close() is doing nothing in your code and you don't need to use ;.
It is very likely that the pickled file is empty.
It is surprisingly easy to overwrite a pickle file if you're copying and pasting code.
For example the following writes a pickle file:
pickle.dump(df,open('df.p','wb'))
And if you copied this code to reopen it, but forgot to change 'wb' to 'rb' then you would overwrite the file:
df=pickle.load(open('df.p','wb'))
The correct syntax is
df=pickle.load(open('df.p','rb'))
As you see, that's actually a natural error ..
A typical construct for reading from an Unpickler object would be like this ..
try:
data = unpickler.load()
except EOFError:
data = list() # or whatever you want
EOFError is simply raised, because it was reading an empty file, it just meant End of File ..
You can catch that exception and return whatever you want from there.
open(target, 'a').close()
scores = {};
try:
with open(target, "rb") as file:
unpickler = pickle.Unpickler(file);
scores = unpickler.load();
if not isinstance(scores, dict):
scores = {};
except EOFError:
return {}
if path.exists(Score_file):
try :
with open(Score_file , "rb") as prev_Scr:
return Unpickler(prev_Scr).load()
except EOFError :
return dict()
Had the same issue. It turns out when I was writing to my pickle file I had not used the file.close(). Inserted that line in and the error was no more.
I have encountered this error many times and it always occurs because after writing into the file, I didn't close it. If we don't close the file the content stays in the buffer and the file stays empty.
To save the content into the file, either file should be closed or file_object should go out of scope.
That's why at the time of loading it's giving the ran out of input error because the file is empty. So you have two options :
file_object.close()
file_object.flush(): if you don't wanna close your file in between the program, you can use the flush() function as it will forcefully move the content from the buffer to the file.
This error comes when your pickle file is empty (0 Bytes). You need to check the size of your pickle file first. This was the scenario in my case. Hope this helps!
Note that the mode of opening files is 'a' or some other have alphabet 'a' will also make error because of the overwritting.
pointer = open('makeaafile.txt', 'ab+')
tes = pickle.load(pointer, encoding='utf-8')
temp_model = os.path.join(models_dir, train_type + '_' + part + '_' + str(pc))
# print(type(temp_model)) # <class 'str'>
filehandler = open(temp_model, "rb")
# print(type(filehandler)) # <class '_io.BufferedReader'>
try:
pdm_temp = pickle.load(filehandler)
except UnicodeDecodeError:
pdm_temp = pickle.load(filehandler, fix_imports=True, encoding="latin1")
from os.path import getsize as size
from pickle import *
if size(target)>0:
with open(target,'rb') as f:
scores={i:j for i,j in enumerate(load(f))}
else: scores={}
#line 1.
we importing Function 'getsize' from Library 'OS' sublibrary 'path' and we rename it with command 'as' for shorter style of writing. Important is hier that we loading only one single Func that we need and not whole Library!
line 2.
Same Idea, but when we dont know wich modul we will use in code at the begining, we can import all library using a command '*'.
line 3.
Conditional Statement... if size of your file >0 ( means obj is not an empty). 'target' is variable that schould be a bit earlier predefined.
just an Example : target=(r'd:\dir1\dir.2..\YourDataFile.bin')
Line 4.
'With open(target) as file:' an open construction for any file, u dont need then to use file.close(). it helps to avoid some typical Errors such as "Run out of input" or Permissions rights.
'rb' mod means 'rea binary' that u can only read(load) the data from your binary file but u cant modify/rewrite it.
Line5.
List comprehension method in applying to a Dictionary..
line 6. Case your datafile is empty, it will not raise an any Error msg, but return just an empty dictionary.

Python with statement - is there a need for old-style file handling any more?

With having the with statement, is there ever a need to open a file/check for exceptions/do manual closing of resources, like in
try:
f = open('myfile.txt')
for line in f:
print line
except IOError:
print 'Could not open/read file'
finally:
f.close()
Your current code tries to handle the exception of the file not being found, or of insufficient access permissions etc., which a with open(file) as f: block wouldn't have done.
Also, in this case, the finally: block would have raised a NameError since f wouldn't have been defined.
In a with block, any exception (of whatever kind, maybe a division by zero in your code) that occurs within the block will still be raised, but even if you don't handle it, your file will always be closed properly. That's something entirely different.
What you want is probably:
try:
with open("myfile.txt") as f:
do_Stuff() # even if this raises an exception, f will be closed.
except IOError:
print "Couldn't open/read myfile.txt"

Categories

Resources