Skip to content
Advertisement

ValueError: write() requires mode ‘w’, ‘x’, or ‘a’ in Python zipfile

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:

  1. Both zip file and the file in the zip file should be opened for writing.
  2. 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.
  3. 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')
User contributions licensed under: CC BY-SA
1 People found this is helpful
Advertisement