Could you helpme to make this exmaple work?
I'd like to load a serialized dict if it exists, modify it and dump it again. I think I have a problem with the mode I'm using to open the file but I don't know the correct way.
import os
import cPickle as pickle
if os.path.isfile('file.txt'):
cache_file = open('file.txt', 'rwb')
cache = pickle.load(cache_file)
else:
cache_file = open('file.txt', 'wb')
cache = dict.fromkeys([1,2,3])
# modifications of cache
pickle.dump(cache, cache_file)
cache_file.close()
Run it twice to see the error:
Traceback (most recent call last):
File "example.py", line 11, in <module>
pickle.dump(cache, cache_file)
IOError: [Errno 9] Bad file descriptor
'rwb' is not correct file open mode for open(). Try 'r+b'.
And after you have read from file, you have cursor positioned at the end of file, so pickle.dump(cache, cache_file) will append to the file (which is probably not what you want). Try cache_file.seek(0) after pickle.load(cache_file).
For each load, you need to open(with mode='rb'), load, and close the file handle.
For each dump, you need to open(with mode='wb'), dump, and close the file handle.
You have opened the file for reading and writing - i.e. random access. When you initially read the file you leave the file index position at the end of the file, so when you later write the data back you are appending to the same file.
You should open the file in read mode, read the data, close it, then reopen in write mode.
Related
I am trying to open a specific file in the archive and then write some content to it. I am using the zipfile.open() function to get access to the file:
import zipfile
my_zip = zipfile.ZipFile('D:\\files\\acrhive.zip')
with my_zip.open('hello.txt', 'w') as my_file:
my_file.write(b'Hello')
my_zip.close()
However, it gives me a warning about duplicate file called 'hello.txt'. After that I get the following error:
ValueError: write() requires mode 'w', 'x', or 'a'
What am I doing wrong here?
My full traceback:
D:\python\lib\zipfile.py:1506: UserWarning: Duplicate name: 'hello.txt'
return self._open_to_write(zinfo, force_zip64=force_zip64)
Traceback (most recent call last):
File "D:\files\python.py", line 8, in <module>
with my_zip.open(file, 'w') as my_file:
File "D:\python\lib\zipfile.py", line 1506, in open
return self._open_to_write(zinfo, force_zip64=force_zip64)
File "D:\python\lib\zipfile.py", line 1598, in _open_to_write
self._writecheck(zinfo)
File "D:\python\lib\zipfile.py", line 1699, in _writecheck
raise ValueError("write() requires mode 'w', 'x', or 'a'")
ValueError: write() requires mode 'w', 'x', or 'a'
Right now you're opening the file in the archive file for writing, but the archive file itself only for reading (the default mode).
The key here is that to the file system, the files inside the archive do not really exist as real files. To the file system they are just bytes inside the archive file. The zipfile library, like many file managers, just goes out of its way to give them to you as virtual files - something that mostly looks and works like a normal file to make it easier to work with them the same way.
So try opening the zip file itself for writing too:
zipfile.ZipFile('D:\\files\\archive.zip', 'w')
Couple notes:
Both zip file and the file in the zip file should be opened for writing.
In the question code you posted, it looks like you have a typo in the zip file name: acrhive.zip vs archive.zip. If my answer code starts failing for you with "file not found", that might be why.
You should just open the zip file with a context manager too, just as with other files and file-like things.
So putting it all together:
with zipfile.ZipFile('D:\\files\\archive.zip', 'w') as my_zip:
with my_zip.open('hello.txt', 'w') as my_file:
my_file.write(b'Hello')
I'm trying to write a function that would use a loop to write multiple files, but it's not succeeding. Here are the code, and the result. The directory does exist; I was able to write, read, and append single files to it with no problem. This was done in the ordinary Python 3.9 interactive command line window on Windows 10.
def writepages(i):
for j in range(i):
name = f"0{j}0page.html"
file = open(f'C:\\Users\\cumminjm\\Documents\\{name}', 'r+')
file.close()
>>>
>>> writepages(5)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 4, in writepages
FileNotFoundError: [Errno 2] No such file or directory: 'C:\\Users\\cumminjm\\Documents\\000page.html'
Unlike "w" or "a", "r+" requires that the file already exist; it does not create the file if it does not already exist.
You should use a different file mode — such as:
w to open a (possibly new) file, and empty it if it exists.
a to open a (possibly new) file, but not empty it.
x to open a new file and fail with FileExistsError if it exists.
As #chepner pointed out, r+ opens an existing file for read and write.
According to this answer you can also use os.mknod("newfile.txt"), but it requires root privilege on macOS.
It's a bit off-topic, but you might like to know about pathlib, which gives you an OS-agnostic way to handle file paths, and using a context for the file opening, which is safer than open/close. Here's how I'd probably write that function:
import pathlib
def writepages(i):
"""Write i HTML pages."""
for j in range(i):
fname = pathlib.Path.home() / 'Documents' / f'0{j}0page.html'
with open(fname, 'x') as f:
f.write('')
return
I am trying to open a csv file using the csv module and then trying to read some data off of it using this code.
import csv
def file_open():
input_file=str(input('enter the input file to use'))
while True:
try:
with open(input_file,'r') as grades:
grades_reader=csv.reader(grades, delimiter=',')
break
except FileNotFoundError:
print('FileNotFoundError')
input_file=str(input('enter the input file to use'))
row_num=1
for row in grades_reader:
print('row',row_num,row)
row_num+=1
file_open()
and the file opening seems to be working until it gets to the part where it has to read the data and then it gives me an i/o error saying the file is closed. I am quite new to python and would appreciate any insight on what I did wrong.
also input_file is meant to allow the user to pick any file but I will only be using it to call one file called Grades.csv if that information will help
EDIT: traceback error message.
Traceback (most recent call last):
File "C:\Users\musta\OneDrive\Documents\computer assignment programs\program 4\Program4.py", line 24, in <module>
file_open()
File "C:\Users\musta\OneDrive\Documents\computer assignment programs\program 4\Program4.py", line 18, in file_open
for row in grades_reader:
ValueError: I/O operation on closed file.
The file is closed because your break ends the loop, and the with body, therefore closing the file
You should keep that file reading code within the with indentation.
A csv.reader doesn't load the file into some in-memory list
(I asked this previously, but have since accepted that it is not an issue with openpyxl, so changing tack)
Given an xlsx created on OS X, I open it for writing on that platform using openpyxl load_workbook(). I add some data, then I save it using Workbook.save() (to the same file).
All good on OS X, but when the program, and the XLSX, are transferred onto a Windows machine and executed, I get:
c:\Users\Me\Desktop\ROI>python roi_cut7.py > log.txt
Traceback (most recent call last):
File "roi_cut7.py", line 379, in <module>
main()
File "roi_cut7.py", line 374, in main
processSource(wb, 'Taboola', taboolaSpends, taboolaRevenues)
File "roi_cut7.py", line 276, in processSource
wb.save(r'output.xlsx')
File "C:\Python27\lib\site-packages\openpyxl\workbook\workbook.py", line 298,
in save
save_workbook(self, filename)
File "C:\Python27\lib\site-packages\openpyxl\writer\excel.py", line 198, in sa
ve_workbook
writer.save(filename, as_template=as_template)
File "C:\Python27\lib\site-packages\openpyxl\writer\excel.py", line 180, in sa
ve
archive = ZipFile(filename, 'w', ZIP_DEFLATED, allowZip64=True)
File "C:\Python27\lib\zipfile.py", line 756, in __init__
self.fp = open(file, modeDict[mode])
IOError: [Errno 22] invalid mode ('wb') or filename: 'output.xlsx'
Following extensive investigation, I've tried the following:
chmod 777 on the XLSX before moving it to Windows icacls output.xlsx
Ruling out path issues by using os.join and r'' raw notation
icacls output.xlsx /grant everyone:F on the file after moving it to Windows
Unticking the read-only checkbox under Attributes in the Windows folder Properties
... with no success. The Windows folder is a regular Windows folder. I can write to it both manually with new files, and programmatically. It's just the writing to this XLSX that is the issue.
I could update the script so that it reads from one file and writes to another (newly-created by openpyxl) file, but this workaround will only serve for a single day, since each subsequent day, the program needs to build upon the written file from the previous day, and if the file being read from is unchanged, this breaks down. Interestingly, I notice that if I open the XLSX in Excel, save it as a new file, update my program to read and write to this file new file, and re-execute, it works .... but only once. Every subsequent execution results in the IOError.
What would your next step be?
def functION():
Source_obj = path.relpath("WebSource\EXAMPLE SOURCE.htm")
data = Source_obj.read()
I am having trouble opening this file while located in a sub-directory directly underneath my Python file... is there a better way to open files from ANY directory on my computer?
FileNotFoundError: [Errno 2] No such file or directory: 'WebSource\\EXAMPLE SOURCE.htm'
I can't read from the file because I get the following error:
C:\python34\python.exe G:\Robot\test.py
Process started >>>
Traceback (most recent call last):
File "G:\Robot\test.py", line 118, in <module>
functION()
File "G:\Robot\test.py", line 64, in functION
data = Source_obj.read()
AttributeError: 'str' object has no attribute 'read'
<<< Process finished. (Exit code 1)
================ READY ================
BTW: The file to be read is just a source file from an HTML Chrome webpage.
EDIT
I'm looking for more help with the path and wondering why I get the first mentioned Traceback regarding the path
os.path.relpath() returns a string, not an open file object. You'll need to open a file first; use the open() function:
def functION():
Source_obj = path.relpath(r"WebSource\EXAMPLE SOURCE.htm")
with open(Source_obj) as fileobj:
data = fileobj.read()
with here treats the file object as a context manager; when the indented codeblock under the statement is exited (either because the code completed or an exception occurred), the file object will automatically be closed.
Your Source_obj is just a string, not a file.
def functION():
Source_obj = path.relpath("WebSource\EXAMPLE SOURCE.htm")
with open(Source_obj) as f:
data = f.read()
By open()-ing it you can read from the file. Using the with context manager, the file will be properly closed for you when you leave that block of code.