It would be most helpful if a method could be included in the TarFile
class of the tarfile module and the ZipFile class of the zipfile module
that would remove a particular file (either given by a name or a
TarInfo/ZipInfo object) from the archive.
Usage to remove a single file from an archive would be as follows:
Such a method should probably only apply to archives that are in append
mode as write mode would erase the original archive and read mode should
render the archive immutable.
One possible extra to be included is to allow a list of file names or
ZipInfo/TarInfo objects to be passed into the remove method, such that
all items in the list would be removed from the archive.
"Such a method should probably only apply to archives that are in append
mode as write mode would erase the original archive and read mode should
render the archive immutable."
The method should probably still apply to an archive in write mode. It
is conceivable that one may need to delete a file from the archive after
it has been written but before the archive object has been closed.
loewis commented on Sep 2, 2009
loewismannequin
Mannequin
More actions
-1. I don't think this can be implemented in a reasonable way, assuming
that you want the file to become smaller as a consequence of removal.
gustaebel commented on Sep 2, 2009
gustaebelmannequin
Mannequin
More actions
-1, although I can only speak for tarfile. Removing members from a tar
archive sounds obvious and easy but it is *not*. A file in an archive is
stored as a header block (that contains the metadata) followed by a
number of data blocks (that contain the file's data). New files are
simply appended to the archive file. There is no central table of
contents whatsoever. To make things worse, a compressed archive is
compressed in one go from the beginning right up to the end, it is not
possible to access a member in the middle of an archive without having
to decompress all data before it.
Deleting files from an uncompressed archive is rather straightforward
implementation-wise but IO intensive and risky. In contrast, there is no
other way to delete files from a *compressed* tarfile than to make a
copy of it omitting the unwanted files.
rossmclendon commented on Sep 2, 2009
rossmclendonmannequin
MannequinAuthor
More actions
In light of Lars's comment on the matter, perhaps this functionality
could be added to zip files only. Surely it can be done, considering
that numerous utilities and even Windows Explorer provide such
functionality. I must confess that I am unfamiliar with the inner
workings of file archives and compression, but seeing as it is
implemented in a number of places already, it seems logical that it
could be implemented in ZipFile as well. I'll spend some time the next
few days educating myself about zip files and how this might be
accomplished.
loewis commented on Sep 2, 2009
loewismannequin
Mannequin
More actions
In light of Lars's comment on the matter, perhaps this functionality
could be added to zip files only. Surely it can be done, considering
that numerous utilities and even Windows Explorer provide such
functionality.
Are you sure they are not creating a new file in order to delete
content? I recall that early zip tools (e.g. pkzip) had a mode
where they would merely delete the entry from the directory, but
leave the actual data in the file. Would you consider that a correct
implementation? If so, *that* can be done, for zipfiles, AFAIU.
I'll spend some time the next
few days educating myself about zip files and how this might be
accomplished.
Please do - you'll find that deletion from zipfiles comes in a can
full of worms.
victorlee129 commented on Oct 26, 2009
victorlee129mannequin
Mannequin
More actions
I done it In a very *violent* way.
Is it ok for you thought?
if so, would anybody please fix it into the lib?
I done it In a very *violent* way.
Is it ok for you thought?
In the form in which you have done it, it is clearly
unacceptable for inclusion in the library: we don't
want to add two modules "delete" and "classtools".
In addition, notice that code is for tarfile, whereas
the OP was asking for a similar feature for zipfile.
if so, would anybody please fix it into the lib?
This is not how this works. If you want us to take
action, please submit a complete and correct patch.
chroipahtz commented on Jul 3, 2010
chroipahtzmannequin
Mannequin
More actions
I have attempted to implement a ZipFile.remove function. It seems to work fine. I have submitted a patch.
The method of implementation is: find the file's index in the file list, then sum the lengths of the file entries before it to find its location in the archive. Then simply read in all the bytes after it, write them out at that location, and truncate the file x bytes shorter, where x is the length of the record. This works because the directory listing is created when the file is closed, so there's no harm in truncating.
I've also made it truncate the zip file after reading in the existing files upon creation, because the directory information is not used after this point.
This could use some testing on large files.
This is my first patch, so let me know if I've done anything wrong.
chroipahtz commented on Jul 3, 2010
chroipahtzmannequin
Mannequin
More actions
My patch had some bugs, I'll need to do some more testing. Sorry about that.
Activity
rossmclendon commented on Sep 2, 2009
It would be most helpful if a method could be included in the TarFile
class of the tarfile module and the ZipFile class of the zipfile module
that would remove a particular file (either given by a name or a
TarInfo/ZipInfo object) from the archive.
Usage to remove a single file from an archive would be as follows:
Such a method should probably only apply to archives that are in append
mode as write mode would erase the original archive and read mode should
render the archive immutable.
One possible extra to be included is to allow a list of file names or
ZipInfo/TarInfo objects to be passed into the remove method, such that
all items in the list would be removed from the archive.
rhettinger commented on Sep 2, 2009
+1
rossmclendon commented on Sep 2, 2009
Slight change to:
"Such a method should probably only apply to archives that are in append
mode as write mode would erase the original archive and read mode should
render the archive immutable."
The method should probably still apply to an archive in write mode. It
is conceivable that one may need to delete a file from the archive after
it has been written but before the archive object has been closed.
loewis commented on Sep 2, 2009
-1. I don't think this can be implemented in a reasonable way, assuming
that you want the file to become smaller as a consequence of removal.
gustaebel commented on Sep 2, 2009
-1, although I can only speak for tarfile. Removing members from a tar
archive sounds obvious and easy but it is *not*. A file in an archive is
stored as a header block (that contains the metadata) followed by a
number of data blocks (that contain the file's data). New files are
simply appended to the archive file. There is no central table of
contents whatsoever. To make things worse, a compressed archive is
compressed in one go from the beginning right up to the end, it is not
possible to access a member in the middle of an archive without having
to decompress all data before it.
Deleting files from an uncompressed archive is rather straightforward
implementation-wise but IO intensive and risky. In contrast, there is no
other way to delete files from a *compressed* tarfile than to make a
copy of it omitting the unwanted files.
rossmclendon commented on Sep 2, 2009
In light of Lars's comment on the matter, perhaps this functionality
could be added to zip files only. Surely it can be done, considering
that numerous utilities and even Windows Explorer provide such
functionality. I must confess that I am unfamiliar with the inner
workings of file archives and compression, but seeing as it is
implemented in a number of places already, it seems logical that it
could be implemented in ZipFile as well. I'll spend some time the next
few days educating myself about zip files and how this might be
accomplished.
loewis commented on Sep 2, 2009
Are you sure they are not creating a new file in order to delete
content? I recall that early zip tools (e.g. pkzip) had a mode
where they would merely delete the entry from the directory, but
leave the actual data in the file. Would you consider that a correct
implementation? If so, *that* can be done, for zipfiles, AFAIU.
Please do - you'll find that deletion from zipfiles comes in a can
full of worms.
victorlee129 commented on Oct 26, 2009
I done it In a very *violent* way.
Is it ok for you thought?
if so, would anybody please fix it into the lib?
loewis commented on Oct 26, 2009
In the form in which you have done it, it is clearly
unacceptable for inclusion in the library: we don't
want to add two modules "delete" and "classtools".
In addition, notice that code is for tarfile, whereas
the OP was asking for a similar feature for zipfile.
This is not how this works. If you want us to take
action, please submit a complete and correct patch.
chroipahtz commented on Jul 3, 2010
I have attempted to implement a ZipFile.remove function. It seems to work fine. I have submitted a patch.
The method of implementation is: find the file's index in the file list, then sum the lengths of the file entries before it to find its location in the archive. Then simply read in all the bytes after it, write them out at that location, and truncate the file x bytes shorter, where x is the length of the record. This works because the directory listing is created when the file is closed, so there's no harm in truncating.
I've also made it truncate the zip file after reading in the existing files upon creation, because the directory information is not used after this point.
This could use some testing on large files.
This is my first patch, so let me know if I've done anything wrong.
chroipahtz commented on Jul 3, 2010
My patch had some bugs, I'll need to do some more testing. Sorry about that.
90 remaining items
pythongh-51067: Use io.DEFAULT_BUFFER_SIZE in no-sig DD scan
pythongh-51067: Replace ComparableZipInfo class with a function
pythongh-51067: Add _REPACK_CHUNK_SIZE constant
pythongh-51067: Add tests for entry-size overshoot and _copy_bytes EOF
gh-51067: Add `remove()` and `repack()` to `ZipFile` (GH-134627)
gpshead commented on Jun 20, 2026
thanks for the contributions and discussion, danny0838's version of this has been merged.
pythongh-51067: Rephrase doc for `ZipFile.{remove,repack}` (pythonGH-…
pythongh-51067: Extract `_read_local_file_header()` as a module-level…
gh-51067: Refactor duplicated logic in `zipfile` to `_read_local_file…
pythongh-51067: Add `remove()` and `repack()` to `ZipFile` (pythonGH-…
Merge branch 'main' into pythongh-51067-6
gh-51067: Remove trailing space in `_Repacker.repack()` error message (…