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:pythonlibzipfile.py:1506: UserWarning: Duplicate name: 'hello.txt' return self._open_to_write(zinfo, force_zip64=force_zip64) Traceback (most recent call last): File "D:filespython.py", line 8, in <module> with my_zip.open(file, 'w') as my_file: File "D:pythonlibzipfile.py", line 1506, in open return self._open_to_write(zinfo, force_zip64=force_zip64) File "D:pythonlibzipfile.py", line 1598, in _open_to_write self._writecheck(zinfo) File "D:pythonlibzipfile.py", line 1699, in _writecheck raise ValueError("write() requires mode 'w', 'x', or 'a'") ValueError: write() requires mode 'w', 'x', or 'a'
Advertisement
Answer
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
vsarchive.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')