File is automatically closed - python

f1 = open("D:/Studies/Python/IDEs/PyCharm/Basics/Basics.py", 'r')
print(next(f1))
The error is:
ValueError: I/O operation on closed file.
I'm trying to access this file from a program which is located in another path:-("D:\Studies\Python\IDEs\PyCharm\File IO\File_IO_Basics.py")
Is that a problem?
If there's any other problem please mention.

Most probably your file has not been opened successfully. Try to include a try ... except near your open command and make sure that way that the file has really been opened:
try:
f1 = open("D:/Studies/Python/IDEs/PyCharm/Basics/Basics.py", 'r')
print "File has been opened"
print(next(f1))
except:
print "File has not been opened"
You could also check whether your file exists at that path using:
import os
if os.path.exists("C:\..."):
print "File exists"

Related

How do I remove and then open a file for writing in python?

Here is some code.
sbfldr = input('Enter subfolder name: ')
try:
os.remove(os.path.join(sbfldr, 'Report.html'))
except:
print('Remove error. Please close the report file')
exit()
try:
fwrite = open(os.path.join(sbfldr, 'Report.html'),'a')
exit()
except:
print('Open error. Please close the report file')
exit()
The results I expect are
If an old version of 'Report.html' exists, then remove it.
Open a new 'Report.html' for writing.
When I search for this question I get lots of answers (to other questions). This is probably because the answer is very easy, but I just do not understand how to do it.
There's no need to remove the file when you can just empty it. File mode w will "open for writing, truncating the file first", and if the file doesn't exist, it will create it.
sbfldr = input('Enter subfolder name: ')
fname = os.path.join(sbfldr, 'Report.html')
with open(fname, 'w') as fwrite:
pass # Actual code here
BTW this uses a with-statement, which is the best practice for opening files. As well it ignores the bad error handling (bare except) and unnecessary exit() in your program.
Thanks to #furas for mentioning this in the comments
Try the following, using os.path.exists to check if the file exists, and os.remove to remove it if so:
import os
if os.path.exists("Report.html"):
os.remove("Report.html")
with open("Report.html", "w") as f:
pass #do your thing

Zipfile closed within context manager [duplicate]

This question already has answers here:
Python: prevent mixed tabs/spaces on module import
(1 answer)
Indentation Error in Python [duplicate]
(7 answers)
Closed 5 years ago.
The following code is confusing the mess out of me. I've got a zip file which I am opening in a context manager. I'm trying to extract the contents of this zip file to a temporary directory. However, when I execute this code block, it tells me that there was an "Attempt to read ZIP archive that was already closed". I find this very strange, as the zip file in question was opened in (with?) a context manager! I've inserted several print statements for calls to methods/properties associated with the object at hand. They return successfully.
Where have I gone wrong? Why does the file believe itself closed?
Any help would be appreciated!
(Edit) Please find the traceback below.
Also, is there a better way to check if a zipfile is in fact open? Other than checking if .fp is True/False?
if config.get('settings', 'new_quarter') == "Yes":
#This gets the latest zip file, by year and quarter
new_statements_path = os.path.join(config.get('cleaning', 'historic_dir'), 'sql_files')
for directory,dirnames, filenames in os.walk(new_statements_path):
zips = [f for f in filenames if ".zip" in f]
highest_quarter = max([z.split('Q')[1].split('.')[0] for z in zips])
print 'Targeting this quarter for initial tables: %s' % (highest_quarter)
for z in zips:
if 'sql_files' in f:
if z.split('Q')[1].split('.')[0] == highest_quarter:
with zipfile.ZipFile(os.path.join(directory,z), 'r') as zip_f:
print zip_f.fp
initial_tables = tempfile.mkdtemp()
print 'initial tables', initial_tables, os.path.exists(initial_tables)
#Ensure the file is read/write by the creator only
saved_umask = os.umask(0077)
try:
print zip_f.namelist()
print zip_f.fp
zip_f.printdir()
zip_f.extractall(path=initial_tables)
except:
print traceback.format_exc()
os.umask(saved_umask)
if os.path.exists(initial_tables) == True:
shutil.rmtree(initial_tables)
Traceback:
Traceback (most recent call last):
File "/Users/n/GitHub/s/s/s/extract/extract.py", line 60, in extract_process
zip_f.extractall(path=initial_tables)
File "/Users/n/anaconda/lib/python2.7/zipfile.py", line 1043, in extractall
self.extract(zipinfo, path, pwd)
File "/Users/n/anaconda/lib/python2.7/zipfile.py", line 1031, in extract
return self._extract_member(member, path, pwd)
File "/Users/n/anaconda/lib/python2.7/zipfile.py", line 1085, in _extract_member
with self.open(member, pwd=pwd) as source, \
File "/Users/n/anaconda/lib/python2.7/zipfile.py", line 946, in open
"Attempt to read ZIP archive that was already closed"
RuntimeError: Attempt to read ZIP archive that was already closed
(SECOND EDIT)
Here's the (reasonably) minimal & complete version. In this case, the code runs fine. Which makes sense, there's nothing fancy going on. What's interesting is I placed the full example (the one below) immediately above the previous example (above). The code below still executes just fine, but the code above still produces the same error. The only difference however is the new_statements_path variable. In the code above, this string comes from a config file. Surely, this isn't the root of the error. But I can't see any other differences.
import traceback
import os
import zipfile
import tempfile
import shutil
new_statements_path = '/Users/n/Official/sql_files'
for directory,dirnames, filenames in os.walk(new_statements_path):
zips = [f for f in filenames if ".zip" in f]
highest_quarter = max([z.split('Q')[1].split('.')[0] for z in zips])
print 'Targeting this Quarter for initial tables: %s' % (highest_quarter)
for z in zips:
if 'sql_files' in f:
if z.split('Q')[1].split('.')[0] == highest_quarter:
with zipfile.ZipFile(os.path.join(directory,z), 'r') as zip_f:
print zip_f.fp
initial_tables = tempfile.mkdtemp()
print 'initial tables', initial_tables, os.path.exists(initial_tables)
#Ensure the file is read/write by the creator only
saved_umask = os.umask(0077)
try:
print zip_f.namelist()
print zip_f.fp
zip_f.printdir()
zip_f.extractall(path=initial_tables)
except:
print traceback.format_exc()
os.umask(saved_umask)
if os.path.exists(initial_tables) == True:
shutil.rmtree(initial_tables)
if os.path.exists(initial_tables) == True:
shutil.rmtree(initial_tables)

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.

Open a file for writing

When i try to open a file, even if it is not opened until that moment, it gives an error about that and therefore i cant write on it. Here is my python code:
try:
myfile = open("SolvedFromFile.xls", "r+")
except IOError:
mesaj=u"Açık olan nokta listesini kapatın!"
wx.MessageBox(mesaj, u"UYARI")
What can cause that?
Thanks in advance.
e.g. you script has no rights to read...rarely happens on your own computer. most seen on productive environment.
or file not found(?)
You have to check the caught exception to see what the cause is:
try:
myfile = open(...)
except IOError as (errno, strerror):
print 'Error code %d: %s' % (errno, strerror)
Give the full address in the open() method. Also check if the file exists or not and your have rights to that location. All the best.

display an error message when file is empty - proper way?

hi im slowly trying to learn the correct way to write python code. suppose i have a text file which i want to check if empty, what i want to happen is that the program immediately terminates and the console window displays an error message if indeed empty. so far what ive done is written below. please teach me the proper method on how one ought to handle this case:
import os
def main():
f1name = 'f1.txt'
f1Cont = open(f1name,'r')
if not f1Cont:
print '%s is an empty file' %f1name
os.system ('pause')
#other code
if __name__ == '__main__':
main()
There is no need to open() the file, just use os.stat().
>>> #create an empty file
>>> f=open('testfile','w')
>>> f.close()
>>> #open the empty file in read mode to prove that it doesn't raise IOError
>>> f=open('testfile','r')
>>> f.close()
>>> #get the size of the file
>>> import os
>>> import stat
>>> os.stat('testfile')[stat.ST_SIZE]
0L
>>>
The pythonic way to do this is:
try:
f = open(f1name, 'r')
except IOError as e:
# you can print the error here, e.g.
print(str(e))
Maybe a duplicate of this.
From the original answer:
import os
if (os.stat(f1name).st_size == 0)
print 'File is empty!'
If file open succeeds the value of 'f1Cont` will be a file object and will not be False (even if the file is empty).One way you can check if the file is empty (after a successful open) is :
if f1Cont.readlines():
print 'File is not empty'
else:
print 'File is empty'
Assuming you are going to read the file if it has data in it, I'd recommend opening it in append-update mode and seeing if the file position is zero. If so, there's no data in the file. Otherwise, we can read it.
with open("filename", "a+") as f:
if f.tell():
f.seek(0)
for line in f: # read the file
print line.rstrip()
else:
print "no data in file"
one can create a custom exception and handle that using a try and except block as below
class ContentNotFoundError(Exception):
pass
with open('your_filename','r') as f:
try:
content=f.read()
if not content:
raise ContentNotFoundError()
except ContentNotFoundError:
print("the file you are trying to open has no contents in it")
else:
print("content found")
print(content)
This code will print the content of the file given if found otherwise will print the message
the file you are trying to open has no contents in it

Categories

Resources