# 40. File Compression

Here are 10 Python snippets demonstrating how to compress and extract files using `gzip`, `bz2`, and `zipfile` modules:

***

**1. Compressing Files Using `gzip`**

This example compresses a text file using the `gzip` module.

```python
import gzip
import shutil

def compress_file(input_file, output_file):
    with open(input_file, 'rb') as f_in:
        with gzip.open(output_file, 'wb') as f_out:
            shutil.copyfileobj(f_in, f_out)

compress_file('example.txt', 'example.txt.gz')
```

This script reads the content of `example.txt` and writes the compressed data into `example.txt.gz`.

***

**2. Extracting Files Using `gzip`**

To decompress a `.gz` file, you can use the following code:

```python
import gzip
import shutil

def decompress_file(input_file, output_file):
    with gzip.open(input_file, 'rb') as f_in:
        with open(output_file, 'wb') as f_out:
            shutil.copyfileobj(f_in, f_out)

decompress_file('example.txt.gz', 'example_decompressed.txt')
```

This script decompresses `example.txt.gz` and saves the result into `example_decompressed.txt`.

***

**3. Compressing Files Using `bz2`**

This snippet shows how to compress a file using the `bz2` module.

```python
import bz2

def compress_file_bz2(input_file, output_file):
    with open(input_file, 'rb') as f_in:
        with bz2.open(output_file, 'wb') as f_out:
            f_out.writelines(f_in)

compress_file_bz2('example.txt', 'example.txt.bz2')
```

This script compresses `example.txt` and writes the compressed content into `example.txt.bz2`.

***

**4. Extracting Files Using `bz2`**

To extract the content from a `.bz2` file, use this code:

```python
import bz2

def decompress_file_bz2(input_file, output_file):
    with bz2.open(input_file, 'rb') as f_in:
        with open(output_file, 'wb') as f_out:
            f_out.writelines(f_in)

decompress_file_bz2('example.txt.bz2', 'example_decompressed.txt')
```

This decompresses `example.txt.bz2` into `example_decompressed.txt`.

***

**5. Creating a ZIP Archive Using `zipfile`**

You can compress multiple files into a zip archive like this:

```python
import zipfile

def create_zip_archive(zip_name, *files):
    with zipfile.ZipFile(zip_name, 'w') as zipf:
        for file in files:
            zipf.write(file)

create_zip_archive('archive.zip', 'example.txt', 'example2.txt')
```

This script creates a `archive.zip` containing `example.txt` and `example2.txt`.

***

**6. Extracting a ZIP Archive Using `zipfile`**

To extract the contents of a ZIP file, use:

```python
import zipfile

def extract_zip_archive(zip_name, output_dir):
    with zipfile.ZipFile(zip_name, 'r') as zipf:
        zipf.extractall(output_dir)

extract_zip_archive('archive.zip', 'output_dir')
```

This extracts all files from `archive.zip` to the `output_dir`.

***

**7. Listing Contents of a ZIP Archive Using `zipfile`**

You can list the files in a ZIP archive like this:

```python
import zipfile

def list_zip_contents(zip_name):
    with zipfile.ZipFile(zip_name, 'r') as zipf:
        print(zipf.namelist())

list_zip_contents('archive.zip')
```

This prints the names of the files inside `archive.zip`.

***

**8. Compressing a String into a ZIP Archive Using `zipfile`**

You can also compress data directly from a string:

```python
import zipfile
import io

def compress_string_to_zip(data, zip_name, file_name_in_zip):
    with zipfile.ZipFile(zip_name, 'w') as zipf:
        with zipf.open(file_name_in_zip, 'w') as f:
            f.write(data.encode())

compress_string_to_zip("Hello, world!", "string_archive.zip", "hello.txt")
```

This creates a ZIP archive `string_archive.zip` containing `hello.txt` with the string content "Hello, world!".

***

**9. Compressing a Directory Using `zipfile`**

Compress a whole directory into a ZIP file:

```python
import zipfile
import os

def zip_directory(directory, zip_name):
    with zipfile.ZipFile(zip_name, 'w', zipfile.ZIP_DEFLATED) as zipf:
        for root, dirs, files in os.walk(directory):
            for file in files:
                zipf.write(os.path.join(root, file), os.path.relpath(os.path.join(root, file), directory))

zip_directory('my_folder', 'my_folder.zip')
```

This will zip the entire `my_folder` directory into `my_folder.zip`.

***

**10. Extracting Specific Files from a ZIP Archive**

You can extract specific files from a ZIP archive like this:

```python
import zipfile

def extract_file_from_zip(zip_name, file_name, output_path):
    with zipfile.ZipFile(zip_name, 'r') as zipf:
        zipf.extract(file_name, output_path)

extract_file_from_zip('archive.zip', 'example.txt', 'output_dir')
```

This extracts `example.txt` from `archive.zip` to the `output_dir`.

***

These snippets demonstrate how to work with file compression and extraction using the `gzip`, `bz2`, and `zipfile` modules in Python. You can choose the one that best fits your use case, whether you are working with single files, directories, or even in-memory strings.
