What are the differences between zip::write::FileOptions and zip::write::FileOptionsExtended for controlling compression settings?

zip::write::FileOptions is the standard configuration type for files added to a ZIP archive, supporting common compression methods like Stored (no compression) and Deflate. zip::write::FileOptionsExtended is a newer, more flexible builder that supports additional compression algorithms like Zstandard, BZIP2, and XZ, along with extended file attributes, permissions, and advanced ZIP features. The key distinction is that FileOptions works with the basic zip crate while FileOptionsExtended requires feature flags to enable advanced compression backends, making it suitable for applications needing modern compression or extended file metadata preservation.

Basic FileOptions Usage

use zip::write::FileOptions;
use zip::CompressionMethod;
use std::io::Write;
 
fn main() -> Result<(), Box<dyn std::error::Error>> {
    let file = std::fs::File::create("archive.zip")?;
    let mut zip = zip::ZipWriter::new(file);
    
    // Basic FileOptions for simple compression
    let options = FileOptions::default()
        .compression_method(CompressionMethod::Deflated)
        .compression_level(Some(9));  // Maximum compression
    
    zip.start_file("readme.txt", options)?;
    zip.write_all(b"Hello, World!")?;
    
    // Stored (no compression)
    let stored_options = FileOptions::default()
        .compression_method(CompressionMethod::Stored);
    
    zip.start_file("data.bin", stored_options)?;
    zip.write_all(b"Binary data")?;
    
    zip.finish()?;
    println!("Archive created");
    Ok(())
}

FileOptions handles common compression settings for typical ZIP archives.

Compression Methods in FileOptions

use zip::write::FileOptions;
use zip::CompressionMethod;
 
fn main() {
    // Available compression methods in basic FileOptions
    let stored = FileOptions::default()
        .compression_method(CompressionMethod::Stored);
    
    let deflated = FileOptions::default()
        .compression_method(CompressionMethod::Deflated);
    
    // Note: CompressionMethod enum includes more methods,
    // but FileOptions may not support all without features
    println!("FileOptions supports: Stored, Deflated (with features)");
}

FileOptions supports basic compression with the standard zip crate features.

FileOptionsExtended Overview

use zip::write::FileOptionsExtended;
use zip::CompressionMethod;
 
fn main() {
    // FileOptionsExtended provides additional capabilities
    // Requires enabling specific features in Cargo.toml:
    // [dependencies]
    // zip = { version = "0.6", features = ["zstd", "bzip2"] }
    
    // Basic usage is similar to FileOptions
    let options = FileOptionsExtended::default()
        .compression_method(CompressionMethod::Deflated)
        .compression_level(Some(9));
    
    // But FileOptionsExtended supports more compression methods
    // and extended file attributes
}

FileOptionsExtended extends capabilities with advanced features and compression.

Extended Compression Support

use zip::write::FileOptionsExtended;
use zip::CompressionMethod;
 
fn main() {
    // FileOptionsExtended supports additional compression methods
    // when corresponding features are enabled
    
    // Zstandard compression (requires "zstd" feature)
    #[cfg(feature = "zstd")]
    let zstd_options = FileOptionsExtended::default()
        .compression_method(CompressionMethod::Zstd)
        .compression_level(Some(3));  // Zstd levels: 1-21
    
    // BZIP2 compression (requires "bzip2" feature)
    #[cfg(feature = "bzip2")]
    let bzip2_options = FileOptionsExtended::default()
        .compression_method(CompressionMethod::Bzip2)
        .compression_level(Some(9));  // Bzip2 levels: 1-9
    
    // XZ compression (requires "xz" feature)
    #[cfg(feature = "xz")]
    let xz_options = FileOptionsExtended::default()
        .compression_method(CompressionMethod::Xz);
    
    // Note: FileOptions with basic crate only supports
    // Stored and Deflated without additional features
}

FileOptionsExtended enables modern compression algorithms via feature flags.

Unix Permissions Support

use zip::write::FileOptionsExtended;
use std::fs::File;
use std::io::Write;
 
fn main() -> Result<(), Box<dyn std::error::Error>> {
    // FileOptionsExtended preserves Unix permissions
    let file = File::create("archive.zip")?;
    let mut zip = zip::ZipWriter::new(file);
    
    // Set executable permissions (Unix)
    let executable_options = FileOptionsExtended::default()
        .compression_method(zip::CompressionMethod::Deflated)
        .unix_permissions(0o755);  // rwxr-xr-x
    
    zip.start_file("script.sh", executable_options)?;
    zip.write_all(b"#!/bin/bash\necho 'Hello'")?;
    
    // Regular file with standard permissions
    let regular_options = FileOptionsExtended::default()
        .compression_method(zip::CompressionMethod::Deflated)
        .unix_permissions(0o644);  // rw-r--r--
    
    zip.start_file("config.txt", regular_options)?;
    zip.write_all(b"setting=value")?;
    
    zip.finish()?;
    Ok(())
}

FileOptionsExtended supports Unix permission preservation for extracted files.

File Attributes and Metadata

use zip::write::FileOptionsExtended;
use zip::CompressionMethod;
 
fn main() {
    // FileOptionsExtended supports extended attributes
    
    // Large file support (ZIP64)
    let large_file_options = FileOptionsExtended::default()
        .compression_method(CompressionMethod::Deflated)
        .large_file(true);  // Enable ZIP64 for files > 4GB
    
    // Last modification time
    let dated_options = FileOptionsExtended::default()
        .compression_method(CompressionMethod::Deflated)
        .last_modified_time(
            zip::DateTime::from_date_and_time(2024, 1, 15, 10, 30, 0)?
        );
    
    // Note: FileOptions also supports last_modified_time
    // but FileOptionsExtended provides more metadata options
    
    Ok(())
}

FileOptionsExtended handles large files and extended metadata.

Comparison of Options Types

use zip::write::{FileOptions, FileOptionsExtended};
use zip::CompressionMethod;
 
fn main() {
    // FileOptions - Standard configuration
    let standard = FileOptions::default()
        .compression_method(CompressionMethod::Deflated)
        .compression_level(Some(6));
    
    // FileOptionsExtended - Extended configuration
    let extended = FileOptionsExtended::default()
        .compression_method(CompressionMethod::Deflated)
        .compression_level(Some(6));
    
    // Key differences:
    // 
    // FileOptions:
    // - Basic compression (Stored, Deflate)
    // - Simpler API
    // - Works with minimal dependencies
    // - Standard ZIP compatibility
    
    // FileOptionsExtended:
    // - Extended compression (Zstd, Bzip2, Xz with features)
    // - Unix permissions
    // - Large file support (ZIP64)
    // - Extended file attributes
    // - Requires feature flags for advanced compression
}

Choose based on compression needs and target compatibility.

Migration from FileOptions to FileOptionsExtended

use zip::write::{FileOptions, FileOptionsExtended};
use zip::CompressionMethod;
 
fn main() {
    // Before: Using FileOptions
    let old_options = FileOptions::default()
        .compression_method(CompressionMethod::Deflated)
        .compression_level(Some(9));
    
    // After: Using FileOptionsExtended
    let new_options = FileOptionsExtended::default()
        .compression_method(CompressionMethod::Deflated)
        .compression_level(Some(9));
    
    // Migration is straightforward for basic usage
    // Most methods have the same names and signatures
    
    // Additional FileOptionsExtended methods:
    // - unix_permissions()
    // - large_file()
    // - alignment()
    // - extended_timestamp() (for better compatibility)
}

Migration to FileOptionsExtended is simple for basic use cases.

Compression Level Differences

use zip::write::FileOptionsExtended;
use zip::CompressionMethod;
 
fn main() {
    // Deflate compression levels (1-9)
    let deflate_fast = FileOptionsExtended::default()
        .compression_method(CompressionMethod::Deflated)
        .compression_level(Some(1));  // Fast, less compression
    
    let deflate_best = FileOptionsExtended::default()
        .compression_method(CompressionMethod::Deflated)
        .compression_level(Some(9));  // Slow, best compression
    
    // Zstd compression levels (1-21 typically)
    #[cfg(feature = "zstd")]
    let zstd_options = FileOptionsExtended::default()
        .compression_method(CompressionMethod::Zstd)
        .compression_level(Some(3));  // Default level
    
    // Bzip2 compression levels (1-9)
    #[cfg(feature = "bzip2")]
    let bzip2_options = FileOptionsExtended::default()
        .compression_method(CompressionMethod::Bzip2)
        .compression_level(Some(9));  // Best compression
    
    // None means default level for the method
    let default_level = FileOptionsExtended::default()
        .compression_method(CompressionMethod::Deflated)
        .compression_level(None);  // Use library default
}

Compression levels vary by algorithm; FileOptionsExtended supports modern algorithms.

Feature Flag Dependencies

# Cargo.toml for FileOptionsExtended with advanced compression
 
[dependencies]
zip = { version = "0.6", default-features = false, features = [
    "deflate",           # Deflate compression (usually default)
    "bzip2",             # BZIP2 compression
    "zstd",              # Zstandard compression  
    "xz",                # XZ compression
    "time",              # Time support for timestamps
] }
// Available features depend on Cargo.toml configuration
use zip::write::FileOptionsExtended;
use zip::CompressionMethod;
 
fn main() {
    // Compression methods available only with features:
    // - Zstd requires "zstd" feature
    // - Bzip2 requires "bzip2" feature
    // - Xz requires "xz" feature
    
    // Without features, stick to basic compression
    let basic = FileOptionsExtended::default()
        .compression_method(CompressionMethod::Stored);
    // Or Deflated if "deflate" feature enabled
}

FileOptionsExtended requires feature flags for advanced compression.

Real-World Use Case: Cross-Platform Archive

use zip::write::FileOptionsExtended;
use zip::CompressionMethod;
use std::fs::File;
use std::io::Write;
 
fn create_archive() -> Result<(), Box<dyn std::error::Error>> {
    let file = File::create("backup.zip")?;
    let mut zip = zip::ZipWriter::new(file);
    
    // Compress text files with Deflate
    let text_options = FileOptionsExtended::default()
        .compression_method(CompressionMethod::Deflated)
        .compression_level(Some(9));
    
    zip.start_file("notes.txt", text_options)?;
    zip.write_all(b"Important notes...")?;
    
    // Large binary files with Zstd (better compression)
    #[cfg(feature = "zstd")]
    {
        let large_options = FileOptionsExtended::default()
            .compression_method(CompressionMethod::Zstd)
            .compression_level(Some(3))
            .large_file(true);  // ZIP64 for large files
        
        zip.start_file("large_data.bin", large_options)?;
        // Write large binary data...
    }
    
    // Executable script with Unix permissions
    let script_options = FileOptionsExtended::default()
        .compression_method(CompressionMethod::Deflated)
        .unix_permissions(0o755);
    
    zip.start_file("deploy.sh", script_options)?;
    zip.write_all(b"#!/bin/bash\ndeploy")?;
    
    zip.finish()?;
    Ok(())
}
 
fn main() {
    match create_archive() {
        Ok(_) => println!("Archive created successfully"),
        Err(e) => eprintln!("Error: {}", e),
    }
}

FileOptionsExtended handles diverse file types with appropriate settings.

Compatibility Considerations

use zip::write::{FileOptions, FileOptionsExtended};
use zip::CompressionMethod;
 
fn main() {
    // Standard ZIP readers (most compatible)
    let standard_options = FileOptions::default()
        .compression_method(CompressionMethod::Deflated);
    // Deflate is universally supported
    
    // Modern compression (requires compatible reader)
    // Zstd: Modern tools, better ratio/speed tradeoff
    // Bzip2: Good compression, widely supported on Unix
    // Xz: Best compression, slower, good for software distribution
    
    // For maximum compatibility:
    // - Use Deflated or Stored
    // - Avoid ZIP64 unless files > 4GB
    // - Don't rely on extended attributes
    
    // For internal tools (full control):
    // - Use Zstd for best performance
    // - Enable ZIP64 for safety
    // - Preserve permissions
}

Choose compression based on target audience and compatibility needs.

Performance Comparison

use zip::write::FileOptionsExtended;
use zip::CompressionMethod;
use std::io::Write;
 
fn main() -> Result<(), Box<dyn std::error::Error>> {
    let data = vec![0u8; 1_000_000];  // 1MB of zeros
    
    // Deflate: Good balance, widely compatible
    // - Compression: ~3:1 ratio
    // - Speed: Moderate compression, fast decompression
    
    // Zstd: Better ratio and speed tradeoff
    // - Compression: ~3.5:1 ratio
    // - Speed: Fast compression, fast decompression
    // - Requires "zstd" feature
    
    // Bzip2: Good compression, slower
    // - Compression: ~4:1 ratio
    // - Speed: Slow compression, moderate decompression
    
    // Xz (LZMA2): Best compression, slowest
    // - Compression: ~5:1 ratio
    // - Speed: Very slow compression, moderate decompression
    
    // Stored: No compression
    // - Ratio: 1:1
    // - Speed: Instant (just copy)
    // - Good for already-compressed data (images, videos)
    
    Ok(())
}

Compression choice affects size, speed, and compatibility.

Synthesis

Core distinction:

  • FileOptions: Standard configuration for basic ZIP archives
  • FileOptionsExtended: Extended configuration for modern compression and metadata

FileOptions capabilities:

  • Stored (no compression) and Deflated compression
  • Basic modification timestamps
  • Standard ZIP compatibility
  • Minimal dependencies

FileOptionsExtended additional capabilities:

  • Zstd compression (with "zstd" feature)
  • Bzip2 compression (with "bzip2" feature)
  • Xz compression (with "xz" feature)
  • Unix permission preservation
  • Large file support (ZIP64)
  • Extended file attributes
  • Alignment options

When to use FileOptions:

  • Creating standard ZIP archives
  • Maximum compatibility required
  • Minimal dependencies desired
  • Basic compression needs (Stored, Deflate)

When to use FileOptionsExtended:

  • Modern compression algorithms (Zstd for better performance)
  • Need to preserve Unix permissions
  • Files larger than 4GB (ZIP64)
  • Extended metadata requirements
  • Controlled environment with compatible readers

Key insight: FileOptionsExtended is the modern choice for applications that control both archive creation and extraction, offering better compression and metadata preservation. FileOptions remains appropriate for maximum compatibility with any ZIP reader. The feature flag system in the zip crate means you only compile the compression backends you actually use—choose FileOptionsExtended with Zstd for best performance in controlled environments, or FileOptions with Deflate for universal compatibility.