Zip
ZipArchiver(path: Path)
Bases: Archiver
Handles archiving operations specific to ZIP files.
This class provides a complete interface for manipulating ZIP archives, including reading and writing files, removing entries, and copying content between archives. It automatically selects appropriate compression methods based on file types (images are stored uncompressed, other files are deflated).
The archiver supports:
- Reading individual files from ZIP archives
- Writing new files or updating existing ones
- Removing single files or multiple files in batch
- Copying entire archive contents to a new ZIP file
- Automatic cleanup of partial operations
| ATTRIBUTE | DESCRIPTION |
|---|---|
path |
Path to the ZIP archive file
TYPE:
|
Examples:
>>> archiver = ZipArchiver(Path("my_archive.cbz"))
>>> archiver.write_file("config.json", '{"version": "1.0"}')
>>> data = archiver.read_file("config.json")
>>> archiver.remove_files(["old_config.json"])
Initialize a ZipArchiver with the provided path.
| PARAMETER | DESCRIPTION |
|---|---|
path
|
Path to the ZIP archive file. The file doesn't need to exist yet - it will be created when first written to.
TYPE:
|
Functions
__enter__() -> Self
Context manager entry for Zip archive operations.
| RETURNS | DESCRIPTION |
|---|---|
Self
|
The archiver instance for use in the context.
TYPE:
|
Examples:
>>> with ZipArchiver(Path("archive.cbz")) as archive:
... # Use archive here
... files = archive.get_filename_list()
__exit__(*_: object) -> None
Context manager exit with proper cleanup.
Ensures the archive is properly closed and all caches are cleared to prevent memory leaks and resource issues.
| PARAMETER | DESCRIPTION |
|---|---|
*_
|
Exception information (ignored)
TYPE:
|
Note
This method is called automatically when exiting a 'with' block. It handles exceptions gracefully and always cleans up resources.
copy_from_archive(other_archive: Archiver) -> bool
Copy files from another archive to the ZIP archive.
Creates a new ZIP archive containing all files from the source archive. This completely replaces the current ZIP file's contents. The operation is atomic - if any error occurs, the original archive is left unchanged.
Files are copied with appropriate compression: image files are stored uncompressed while other files are compressed using deflate. Bad or corrupted files in the source archive are skipped with a warning.
| PARAMETER | DESCRIPTION |
|---|---|
other_archive
|
Source archive to copy from. Can be any Archiver implementation (ZIP, RAR, etc.) that supports the read_file() and get_filename_list() methods.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
bool
|
True if all files were successfully copied, False if any error occurred during the copy operation. Partial failures result in cleanup of the incomplete archive. |
Note
- Creates a new ZIP file, replacing any existing content
- Automatically selects compression based on file type
- Skips corrupted files with warnings
- Performs cleanup on partial failures
- Uses ZIP64 format for large archives
Examples:
>>> source = RarArchiver(Path("source.rar"))
>>> target = ZipArchiver(Path("target.cbz"))
>>> success = target.copy_from_archive(source)
>>> if success:
... print("Archive converted successfully")
get_filename_list() -> list[str]
Get a list of all files in the ZIP archive.
Retrieves the complete list of files contained in the ZIP archive. This includes all files and directories, with paths using forward slashes as separators.
| RETURNS | DESCRIPTION |
|---|---|
list[str]
|
List of file paths within the archive. Returns an empty list if the archive cannot be read or is empty. Directory entries (if any) are included in the list. |
Performance
The filename list is cached after first access, so subsequent calls are very fast. Cache is invalidated when files are added or removed.
Note
- Paths use forward slashes regardless of host OS
- Directory entries may be included depending on how the ZIP was created
- Returns empty list on any error (corrupt archive, file not found, etc.)
Examples:
>>> archiver = ZipArchiver(Path("project.cbz"))
>>> files = archiver.get_filename_list()
>>> for file in files:
... print(f"Found: {file}")
read_file(archive_file: str) -> bytes
Read the contents of a file from the ZIP archive.
Opens the ZIP archive in read mode and extracts the specified file's contents. The file path should use forward slashes as separators, following ZIP archive conventions.
| PARAMETER | DESCRIPTION |
|---|---|
archive_file
|
Path of the file within the archive. Should use forward slashes (/) as path separators regardless of the host operating system.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
bytes
|
File contents as bytes. For text files, you may need to decode using the appropriate encoding (e.g., .decode('utf-8')). |
| RAISES | DESCRIPTION |
|---|---|
ArchiverReadError
|
If the file cannot be read due to:
|
Examples:
>>> archiver = ZipArchiver(Path("docs.cbz"))
>>> content = archiver.read_file("readme.txt")
>>> text = content.decode('utf-8')
remove_files(filename_list: list[str]) -> bool
Remove multiple files from the ZIP archive in a single operation.
Efficiently removes multiple files from the ZIP archive by performing all removals in a single transaction and repacking once.
Only files that actually exist in the archive will be removed. Files that don't exist are silently skipped.
| PARAMETER | DESCRIPTION |
|---|---|
filename_list
|
List of file paths to remove from the archive. Each path should use forward slashes (/) as separators.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
bool
|
True if all existing files were successfully removed, False if an error occurred during the removal process. Returns True if the filename_list is empty or contains no existing files. |
Note
- Non-existent files are silently ignored
- All removals are performed in a single transaction
- If any error occurs, no files are removed
- The archive is repacked once after all removals
Examples:
>>> archiver = ZipArchiver(Path("batch_cleanup.cbz"))
>>> files_to_remove = ["temp1.txt", "temp2.txt", "cache.dat"]
>>> success = archiver.remove_files(files_to_remove)
>>> if success:
... print(f"Removed {len(files_to_remove)} files")
test() -> bool
Test whether the file is a valid ZIP archive.
| RETURNS | DESCRIPTION |
|---|---|
bool
|
True if the file is a valid ZIP archive, False otherwise.
TYPE:
|
Note
This method uses the zipfile library to validate the archive structure, not just the file extension.
write_file(archive_file: str, data: str | bytes) -> bool
Write data to a file in the ZIP archive.
Creates a new file or updates an existing file in the ZIP archive. The compression method is automatically selected based on the file extension: image files are stored uncompressed (ZIP_STORED) while other files are compressed using deflate (ZIP_DEFLATED).
If the file already exists in the archive, it will be removed and replaced with the new content using the zipremove library's repack functionality.
| PARAMETER | DESCRIPTION |
|---|---|
archive_file
|
Path of the file within the archive. Should use forward slashes (/) as path separators.
TYPE:
|
data
|
Data to write. Can be either a string (will be UTF-8 encoded) or bytes. Binary data should be passed as bytes.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
bool
|
True if the file was successfully written, False if an error occurred during the write operation. |
Note
- String data is automatically encoded as UTF-8
- Image files (matched by IMAGE_EXT_RE) are stored uncompressed
- Other files are compressed with deflate at maximum compression level
- Existing files are replaced, not appended to
Examples:
>>> archiver = ZipArchiver(Path("data.cbz"))
>>> # Write text content
>>> archiver.write_file("note.txt", "Hello, World!")
>>> # Write binary content
>>> with open("image.jpg", "rb") as f:
... archiver.write_file("image.jpg", f.read())