Struct ZipArchive

pub struct ZipArchive<R> { /* private fields */ }

ZIP archive reader

At the moment, this type is cheap to clone if this is the case for the reader it uses. However, this is not guaranteed by this crate and it may change in the future.

use std::io::{Read, Seek};
fn list_zip_contents(reader: impl Read + Seek) -> zip::result::ZipResult<()> {
    let mut zip = zip::ZipArchive::new(reader)?;

    for i in 0..zip.len() {
        let mut file = zip.by_index(i)?;
        println!("Filename: {}", file.name());
        std::io::copy(&mut file, &mut std::io::stdout())?;
    }

    Ok(())
}

Implementations

impl<R> ZipArchive<R>

fn decompressed_size(&self) -> Option<u128>

Total size of the files in the archive, if it can be known. Doesn't include directories or metadata.

impl<R: Read + Seek> ZipArchive<R>

fn get_aes_verification_key_and_salt(&mut self, file_number: usize) -> ZipResult<Option<AesInfo>>

Returns the verification value and salt for the AES encryption of the file

It fails if the file number is invalid.

Returns

  • None if the file is not encrypted with AES
fn new(reader: R) -> ZipResult<ZipArchive<R>>

Read a ZIP archive, collecting the files it contains.

This uses the central directory record of the ZIP file, and ignores local file headers.

A default Config is used.

fn metadata(&self) -> Arc<ZipArchiveMetadata>

Get the metadata associated with the ZIP archive.

This can be used with Self::unsafe_new_with_metadata to create a new reader over the same file without needing to reparse the metadata.

unsafe fn unsafe_new_with_metadata(reader: R, metadata: Arc<ZipArchiveMetadata>) -> Self

Read a ZIP archive using the given metadata.

This is useful for creating multiple readers over the same file without needing to reparse the metadata.

Safety

unsafe is used here to indicate that reader and metadata could potentially be incompatible, and it is left to the user to ensure they are.

Example

# use std::fs;
use rayon::prelude::*;

const FILE_NAME: &str = "my_data.zip";

let file = fs::File::open(FILE_NAME).unwrap();
let mut archive = zip::ZipArchive::new(file).unwrap();

let file_names = (0..archive.len())
    .into_par_iter()
    .map_init({
        let metadata = archive.metadata().clone();
        move || {
            let file = fs::File::open(FILE_NAME).unwrap();
            unsafe { zip::ZipArchive::unsafe_new_with_metadata(file, metadata.clone()) }
        }},
        |archive, i| {
            let mut file = archive.by_index(i).unwrap();
            file.enclosed_name()
        }
    )
    .filter_map(|name| name)
    .collect::<Vec<_>>();
fn with_config(config: Config, reader: R) -> ZipResult<ZipArchive<R>>

Read a ZIP archive providing a read configuration, collecting the files it contains.

This uses the central directory record of the ZIP file, and ignores local file headers.

fn len(&self) -> usize

Number of files contained in this zip.

fn central_directory_start(&self) -> u64

Get the starting offset of the zip central directory.

fn is_empty(&self) -> bool

Whether this zip archive contains no files

fn offset(&self) -> u64

Get the offset from the beginning of the underlying reader that this zip begins at, in bytes.

Normally this value is zero, but if the zip has arbitrary data prepended to it, then this value will be the size of that prepended data.

fn comment(&self) -> &[u8]

Get the comment of the zip archive.

fn zip64_comment(&self) -> Option<&[u8]>

Get the ZIP64 comment of the zip archive, if it is ZIP64.

fn raw_zip64_extensible_data_sector(&self) -> Option<&[u8]>

Get the ZIP64 extensible_data of the zip archive, if it is ZIP64.

fn file_names(&self) -> impl Iterator<Item = &str>

Returns an iterator over all the file and directory names in this archive.

fn has_overlapping_files(&mut self) -> ZipResult<bool>

Returns Ok(true) if any compressed data in this archive belongs to more than one file. This doesn't make the archive invalid, but some programs will refuse to decompress it because the copies would take up space independently in the destination.

fn by_name_decrypt(&mut self, name: &str, password: &[u8]) -> ZipResult<ZipFile<'_, R>>

Search for a file entry by name, decrypt with given password

Warning

The implementation of the cryptographic algorithms has not gone through a correctness review, and you should assume it is insecure: passwords used with this API may be compromised.

This function sometimes accepts wrong password. This is because the ZIP spec only allows us to check for a 1/256 chance that the password is correct. There are many passwords out there that will also pass the validity checks we are able to perform. This is a weakness of the ZipCrypto algorithm, due to its fairly primitive approach to cryptography.

fn by_name(&mut self, name: &str) -> ZipResult<ZipFile<'_, R>>

Search for a file entry by name

fn index_for_name(&self, name: &str) -> Option<usize>

Get the index of a file entry by name, if it's present.

fn by_path_decrypt<T: AsRef<Path>>(&mut self, path: T, password: &[u8]) -> ZipResult<ZipFile<'_, R>>

Search for a file entry by path, decrypt with given password

Warning

The implementation of the cryptographic algorithms has not gone through a correctness review, and you should assume it is insecure: passwords used with this API may be compromised.

This function sometimes accepts wrong password. This is because the ZIP spec only allows us to check for a 1/256 chance that the password is correct. There are many passwords out there that will also pass the validity checks we are able to perform. This is a weakness of the ZipCrypto algorithm, due to its fairly primitive approach to cryptography.

fn by_path<T: AsRef<Path>>(&mut self, path: T) -> ZipResult<ZipFile<'_, R>>

Search for a file entry by path

fn index_for_path<T: AsRef<Path>>(&self, path: T) -> Option<usize>

Get the index of a file entry by path, if it's present.

fn name_for_index(&self, index: usize) -> Option<&str>

Get the name of a file entry, if it's present.

fn by_name_seek(&mut self, name: &str) -> ZipResult<ZipFileSeek<'_, R>>

Search for a file entry by name and return a seekable object.

fn by_index_seek(&mut self, index: usize) -> ZipResult<ZipFileSeek<'_, R>>

Search for a file entry by index and return a seekable object.

fn by_index_decrypt(&mut self, file_number: usize, password: &[u8]) -> ZipResult<ZipFile<'_, R>>

Get a contained file by index, decrypt with given password

Warning

The implementation of the cryptographic algorithms has not gone through a correctness review, and you should assume it is insecure: passwords used with this API may be compromised.

This function sometimes accepts wrong password. This is because the ZIP spec only allows us to check for a 1/256 chance that the password is correct. There are many passwords out there that will also pass the validity checks we are able to perform. This is a weakness of the ZipCrypto algorithm, due to its fairly primitive approach to cryptography.

fn by_index(&mut self, file_number: usize) -> ZipResult<ZipFile<'_, R>>

Get a contained file by index

fn by_index_raw(&mut self, file_number: usize) -> ZipResult<ZipFile<'_, R>>

Get a contained file by index without decompressing it

fn by_index_with_options(&mut self, file_number: usize, options: ZipReadOptions<'_>) -> ZipResult<ZipFile<'_, R>>

Get a contained file by index with options.

fn root_dir(&self, filter: impl RootDirFilter) -> ZipResult<Option<PathBuf>>

Find the "root directory" of an archive if it exists, filtering out irrelevant entries when searching.

Our definition of a "root directory" is a single top-level directory that contains the rest of the archive's entries. This is useful for extracting archives that contain a single top-level directory that you want to "unwrap" and extract directly.

For a sensible default filter, you can use root_dir_common_filter. For a custom filter, see RootDirFilter.

fn into_inner(self) -> R

Unwrap and return the inner reader object

The position of the reader is undefined.

impl<R: Read + Seek> ZipArchive<R>

fn extract<P: AsRef<Path>>(&mut self, directory: P) -> ZipResult<()>

Extract a Zip archive into a directory, overwriting files if they already exist. Paths are sanitized with ZipFile::enclosed_name. Symbolic links are only created and followed if the target is within the destination directory (this is checked conservatively using std::fs::canonicalize).

Extraction is not atomic. If an error is encountered, some of the files may be left on disk. However, on Unix targets, no newly-created directories with part but not all of their contents extracted will be readable, writable or usable as process working directories by any non-root user except you.

On Unix and Windows, symbolic links are extracted correctly. On other platforms such as WebAssembly, symbolic links aren't supported, so they're extracted as normal files containing the target path in UTF-8.

fn extract_unwrapped_root_dir<P: AsRef<Path>>(&mut self, directory: P, root_dir_filter: impl RootDirFilter) -> ZipResult<()>

Extracts a Zip archive into a directory in the same fashion as ZipArchive::extract, but detects a "root" directory in the archive (a single top-level directory that contains the rest of the archive's entries) and extracts its contents directly.

For a sensible default filter, you can use root_dir_common_filter. For a custom filter, see RootDirFilter.

See ZipArchive::root_dir for more information on how the root directory is detected and the meaning of the filter parameter.

Example

Imagine a Zip archive with the following structure:

root/file1.txt
root/file2.txt
root/sub/file3.txt
root/sub/subsub/file4.txt

If the archive is extracted to foo using ZipArchive::extract, the resulting directory structure will be:

foo/root/file1.txt
foo/root/file2.txt
foo/root/sub/file3.txt
foo/root/sub/subsub/file4.txt

If the archive is extracted to foo using ZipArchive::extract_unwrapped_root_dir, the resulting directory structure will be:

foo/file1.txt
foo/file2.txt
foo/sub/file3.txt
foo/sub/subsub/file4.txt

Example - No Root Directory

Imagine a Zip archive with the following structure:

root/file1.txt
root/file2.txt
root/sub/file3.txt
root/sub/subsub/file4.txt
other/file5.txt

Due to the presence of the other directory, ZipArchive::extract_unwrapped_root_dir will extract this in the same fashion as ZipArchive::extract as there is now no "root directory."

Trait Implementations

impl<R: Clone> Clone for ZipArchive<R>

fn clone(&self) -> ZipArchive<R>

impl<R: Debug> Debug for ZipArchive<R>

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Auto Trait Implementations

impl<R> Freeze for ZipArchive<R> where R: Freeze,

impl<R> RefUnwindSafe for ZipArchive<R> where R: RefUnwindSafe,

impl<R> Send for ZipArchive<R> where R: Send,

impl<R> Sync for ZipArchive<R> where R: Sync,

impl<R> Unpin for ZipArchive<R> where R: Unpin,

impl<R> UnsafeUnpin for ZipArchive<R> where R: UnsafeUnpin,

impl<R> UnwindSafe for ZipArchive<R> where R: UnwindSafe,

Blanket Implementations

impl<T> Any for ZipArchive<R> where T: 'static + ?Sized,

fn type_id(&self) -> TypeId

impl<T> Borrow<T> for ZipArchive<R> where T: ?Sized,

fn borrow(&self) -> &T

impl<T> BorrowMut<T> for ZipArchive<R> where T: ?Sized,

fn borrow_mut(&mut self) -> &mut T

impl<T> CloneToUninit for ZipArchive<R> where T: Clone,

unsafe fn clone_to_uninit(&self, dest: *mut u8)

impl<T> From<T> for ZipArchive<R>

fn from(t: T) -> T

Returns the argument unchanged.

impl<T> Same for ZipArchive<R>

type Output = T;

impl<T> ToOwned for ZipArchive<R> where T: Clone,

type Owned = T;
fn to_owned(&self) -> T
fn clone_into(&self, target: &mut T)

impl<T, U> Into<U> for ZipArchive<R> where U: From<T>,

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of [From]<T> for U chooses to do.

impl<T, U> TryFrom<U> for ZipArchive<R> where U: Into<T>,

type Error = never;
fn try_from(value: U) -> Result<T, never>

impl<T, U> TryInto<U> for ZipArchive<R> where U: TryFrom<T>,

type Error = <U as TryFrom<T>>::Error;
fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>