[](https://codecov.io/gh/xixu-me/tzst)
[](https://github.com/xixu-me/tzst/actions/workflows/github-code-scanning/codeql)
[](https://github.com/xixu-me/tzst/actions/workflows/ci.yml)
[](https://pypi.org/project/tzst/)
[](https://pypistats.org/packages/tzst)
[](LICENSE)
[](https://xi-xu.me/#sponsorships)
[](https://tzst.xi-xu.me)
[๐บ๐ธ English](./README.md) | [๐จ๐ณ ๆฑ่ฏญ](./README.zh.md) | [๐ช๐ธ espaรฑol](./README.es.md) | [๐ฏ๐ต ๆฅๆฌ่ช](./README.ja.md) | [๐ฆ๐ช ุงูุนุฑุจูุฉ](./README.ar.md) | [๐ท๐บ ััััะบะธะน](./README.ru.md) | [๐ฉ๐ช Deutsch](./README.de.md) | [๐ซ๐ท franรงais](./README.fr.md) | **๐ฐ๐ท ํ๊ตญ์ด** | [๐ง๐ท portuguรชs](./README.pt.md)
**tzst**๋ Python 3.12+์์ `.tzst` ๋ฐ `.tar.zst` ์์นด์ด๋ธ๋ฅผ ์์ฑ, ์ถ์ถ, ๋์ด, ๊ฒ์ฌํ๊ธฐ ์ํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ด์ CLI์
๋๋ค. tar ํธํ์ฑ, Zstandard ์์ถ, ์คํธ๋ฆฌ๋ฐ ์ฒ๋ฆฌ, ์์์ ์ฐ๊ธฐ, ๊ธฐ๋ณธ ์์ ์ถ์ถ์ ์ด์ ํ๊ฒฝ์ ์ ํฉํ ๊ฐ๊ฒฐํ ์ธํฐํ์ด์ค๋ก ์ ๊ณตํฉ๋๋ค.
> [!NOTE]
> ์์ธ ๊ธฐ์ ๋ฌธ์: **[Deep Dive into tzst: A Modern Python Archiving Library Based on Zstandard](https://blog.xi-xu.me/2025/11/01/deep-dive-into-tzst-en.html)**.
## ๊ธฐ๋ฅ
- **๊ณ ์์ถ๋ฅ **: ์ฐ์ํ ์์ถ๋ฅ ๊ณผ ์๋๋ฅผ ์ํ Zstandard ์์ถ
- **Tar ํธํ์ฑ**: Zstandard๋ก ์์ถ๋ ํ์ค tar ์์นด์ด๋ธ ์์ฑ
- **๋ช
๋ น์ค ์ธํฐํ์ด์ค**: ์คํธ๋ฆฌ๋ฐ ์ง์๊ณผ ํฌ๊ด์ ์ธ ์ต์
์ ๊ฐ์ถ ์ง๊ด์ ์ธ CLI
- **Python API**: ํ๋ก๊ทธ๋จ์ ์ฌ์ฉ์ ์ํ ๊น๋ํ๊ณ Python ์คํ์ผ์ API
- **ํฌ๋ก์ค ํ๋ซํผ**: Windows, macOS, Linux์์ ์๋
- **๋ค์ค ํ์ฅ์**: `.tzst` ๋ฐ `.tar.zst` ํ์ฅ์ ๋ชจ๋ ์ง์
- **๋ฉ๋ชจ๋ฆฌ ํจ์จ์ **: ์ต์ ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ์ผ๋ก ๋์ฉ๋ ์์นด์ด๋ธ ์ฒ๋ฆฌ ๊ฐ๋ฅํ ์คํธ๋ฆฌ๋ฐ ๋ชจ๋
- **์์์ ์์
**: ์ค๋จ ์ ์๋ ์ ๋ฆฌ ๊ธฐ๋ฅ์ ํตํ ์์ ํ ํ์ผ ์์
- **๊ธฐ๋ณธ ๋ณด์**: ์ถ์ถ ์ ์ต๋ ๋ณด์์ ์ํด 'data' ํํฐ ์ฌ์ฉ
- **ํฅ์๋ ์ค๋ฅ ์ฒ๋ฆฌ**: ์ ์ฉํ ๋์ ์ ์์ ํจ๊ป ๋ช
ํํ ์ค๋ฅ ๋ฉ์์ง
## ์ค์น
### GitHub ๋ฆด๋ฆฌ์ค์์
Python ์ค์น๊ฐ ํ์ ์๋ ๋
๋ฆฝํ ์คํ ํ์ผ ๋ค์ด๋ก๋:
#### ์ง์ ํ๋ซํผ
| ํ๋ซํผ | ์ํคํ
์ฒ | ํ์ผ |
|----------|-------------|------|
| **Linux** | x86_64 | `tzst-{๋ฒ์ }-linux-amd64.zip` |
| **Linux** | ARM64 | `tzst-{๋ฒ์ }-linux-arm64.zip` |
| **Windows** | x64 | `tzst-{๋ฒ์ }-windows-amd64.zip` |
| **Windows** | ARM64 | `tzst-{๋ฒ์ }-windows-arm64.zip` |
| **macOS** | Intel | `tzst-{๋ฒ์ }-darwin-amd64.zip` |
| **macOS** | Apple Silicon | `tzst-{๋ฒ์ }-darwin-arm64.zip` |
#### ์ค์น ๋จ๊ณ
1. [์ต์ ๋ฆด๋ฆฌ์ค ํ์ด์ง](https://github.com/xixu-me/tzst/releases/latest)์์ ํ๋ซํผ์ ๋ง๋ ์์นด์ด๋ธ **๋ค์ด๋ก๋**
2. ์์นด์ด๋ธ๋ฅผ **์ถ์ถ**ํ์ฌ `tzst` ์คํ ํ์ผ ํ๋ (Windows๋ `tzst.exe`)
3. ์คํ ํ์ผ์ PATH ํ๊ฒฝ ๋ณ์ ๋๋ ํฐ๋ฆฌ๋ก **์ด๋**:
- **Linux/macOS**: `sudo mv tzst /usr/local/bin/`
- **Windows**: `tzst.exe`๊ฐ ํฌํจ๋ ๋๋ ํฐ๋ฆฌ๋ฅผ PATH ํ๊ฒฝ ๋ณ์์ ์ถ๊ฐ
4. ์ค์น **ํ์ธ**: `tzst --help`
#### ๋ฐ์ด๋๋ฆฌ ์ค์น์ ์ฅ์
- **Python ๋ถํ์** - ๋
๋ฆฝํ ์คํ ํ์ผ
- **๋น ๋ฅธ ์์** - Python ์ธํฐํ๋ฆฌํฐ ์ค๋ฒํค๋ ์์
- **์ฌ์ด ๋ฐฐํฌ** - ๋จ์ผ ํ์ผ ๋ฐฐํฌ
- **์ผ๊ด๋ ๋์** - ๋ฒ๋ค๋ง๋ ์์กด์ฑ
### PyPI์์
pip ์ฌ์ฉ:
```bash
pip install tzst
```
๋๋ uv ์ฌ์ฉ (๊ถ์ฅ):
```bash
uv tool install tzst
```
### ์์ค์์
```bash
git clone https://github.com/xixu-me/tzst.git
cd tzst
pip install .
```
### ๊ฐ๋ฐ ์ค์น
์ต์ Python ํจํค์ง ํ์ค ์ฌ์ฉ:
```bash
git clone https://github.com/xixu-me/tzst.git
cd tzst
pip install -e .[dev]
```
## ๋น ๋ฅธ ์์
### ๋ช
๋ น์ค ์ฌ์ฉ๋ฒ
```bash
# ์์นด์ด๋ธ ์์ฑ
tzst a archive.tzst file1.txt file2.txt directory/
# ์์นด์ด๋ธ ์ถ์ถ
tzst x archive.tzst
# ์์นด์ด๋ธ ๋ด์ฉ ๋ชฉ๋ก
tzst l archive.tzst
# ์์นด์ด๋ธ ๋ฌด๊ฒฐ์ฑ ํ
์คํธ
tzst t archive.tzst
```
### Python API ์ฌ์ฉ๋ฒ
```python
from tzst import create_archive, extract_archive, list_archive
# ์์นด์ด๋ธ ์์ฑ
create_archive("archive.tzst", ["file1.txt", "file2.txt", "directory/"])
# ์์นด์ด๋ธ ์ถ์ถ
extract_archive("archive.tzst", "output_directory/")
# ์์นด์ด๋ธ ๋ด์ฉ ๋ชฉ๋ก
contents = list_archive("archive.tzst", verbose=True)
for item in contents:
print(f"{item['name']}: {item['size']} bytes")
```
## ๋ช
๋ น์ค ์ธํฐํ์ด์ค
### ์์นด์ด๋ธ ์์
#### ์์นด์ด๋ธ ์์ฑ
```bash
# ๊ธฐ๋ณธ ์ฌ์ฉ๋ฒ
tzst a archive.tzst file1.txt file2.txt
# ์์ถ ๋ ๋ฒจ ์ง์ (1-22, ๊ธฐ๋ณธ๊ฐ: 3)
tzst a archive.tzst files/ -l 15
# ๋์ฒด ๋ช
๋ น์ด
tzst add archive.tzst files/
tzst create archive.tzst files/
```
#### ์์นด์ด๋ธ ์ถ์ถ
```bash
# ์ ์ฒด ๋๋ ํฐ๋ฆฌ ๊ตฌ์กฐ ์ ์งํ๋ฉฐ ์ถ์ถ
tzst x archive.tzst
# ํน์ ๋๋ ํฐ๋ฆฌ๋ก ์ถ์ถ
tzst x archive.tzst -o output/
# ํน์ ํ์ผ ์ถ์ถ
tzst x archive.tzst file1.txt dir/file2.txt
# ๋๋ ํฐ๋ฆฌ ๊ตฌ์กฐ ์์ด ์ถ์ถ (ํ๋ซ)
tzst e archive.tzst -o output/
# ๋์ฉ๋ ์์นด์ด๋ธ์ ์คํธ๋ฆฌ๋ฐ ๋ชจ๋ ์ฌ์ฉ
tzst x archive.tzst --streaming -o output/
```
#### ๋ด์ฉ ๋ชฉ๋ก
```bash
# ๊ฐ๋จํ ๋ชฉ๋ก
tzst l archive.tzst
# ์์ธ ์ ๋ณด ํฌํจ ๋ชฉ๋ก
tzst l archive.tzst -v
# ๋์ฉ๋ ์์นด์ด๋ธ์ ์คํธ๋ฆฌ๋ฐ ๋ชจ๋ ์ฌ์ฉ
tzst l archive.tzst --streaming -v
```
#### ๋ฌด๊ฒฐ์ฑ ํ
์คํธ
```bash
# ์์นด์ด๋ธ ๋ฌด๊ฒฐ์ฑ ํ
์คํธ
tzst t archive.tzst
# ์คํธ๋ฆฌ๋ฐ ๋ชจ๋๋ก ํ
์คํธ
tzst t archive.tzst --streaming
```
### ๋ช
๋ น์ด ์ฐธ์กฐ
| ๋ช
๋ น์ด | ๋ณ์นญ | ์ค๋ช
| ์คํธ๋ฆฌ๋ฐ ์ง์ |
|---------|---------|-------------|-------------------|
| `a` | `add`, `create` | ์์นด์ด๋ธ ์์ฑ ๋๋ ์ถ๊ฐ | N/A |
| `x` | `extract` | ์ ์ฒด ๊ฒฝ๋ก๋ก ์ถ์ถ | โ `--streaming` |
| `e` | `extract-flat` | ๋๋ ํฐ๋ฆฌ ๊ตฌ์กฐ ์์ด ์ถ์ถ | โ `--streaming` |
| `l` | `list` | ์์นด์ด๋ธ ๋ด์ฉ ๋ชฉ๋ก | โ `--streaming` |
| `t` | `test` | ์์นด์ด๋ธ ๋ฌด๊ฒฐ์ฑ ํ
์คํธ | โ `--streaming` |
### CLI ์ต์
- `-v, --verbose`: ์์ธ ์ถ๋ ฅ ํ์ฑํ
- `-o, --output DIR`: ์ถ๋ ฅ ๋๋ ํฐ๋ฆฌ ์ง์ (์ถ์ถ ๋ช
๋ น์ด)
- `-l, --level LEVEL`: ์์ถ ๋ ๋ฒจ 1-22 ์ค์ (์์ฑ ๋ช
๋ น์ด)
- `--streaming`: ๋ฉ๋ชจ๋ฆฌ ํจ์จ์ ์ฒ๋ฆฌ๋ฅผ ์ํ ์คํธ๋ฆฌ๋ฐ ๋ชจ๋ ํ์ฑํ
- `--filter FILTER`: ์ถ์ถ์ ์ํ ๋ณด์ ํํฐ (data/tar/fully_trusted)
- `--no-atomic`: ์์์ ํ์ผ ์์
๋นํ์ฑํ (๊ถ์ฅํ์ง ์์)
### ๋ณด์ ํํฐ
```bash
# ์ต๋ ๋ณด์์ผ๋ก ์ถ์ถ (๊ธฐ๋ณธ๊ฐ)
tzst x archive.tzst --filter data
# ํ์ค tar ํธํ์ฑ์ผ๋ก ์ถ์ถ
tzst x archive.tzst --filter tar
# ์์ ์ ๋ขฐ ๋ชจ๋๋ก ์ถ์ถ (์ํ - ์ ๋ขฐํ ์ ์๋ ์์นด์ด๋ธ ์ ์ฉ)
tzst x archive.tzst --filter fully_trusted
```
**๋ณด์ ํํฐ ์ต์
:**
- `data` (๊ธฐ๋ณธ๊ฐ): ๊ฐ์ฅ ์์ . ์ํํ ํ์ผ, ์ ๋ ๊ฒฝ๋ก, ์ถ์ถ ๋๋ ํฐ๋ฆฌ ์ธ๋ถ ๊ฒฝ๋ก ์ฐจ๋จ
- `tar`: ํ์ค tar ํธํ์ฑ. ์ ๋ ๊ฒฝ๋ก ๋ฐ ๋๋ ํฐ๋ฆฌ ์ํ ์ฐจ๋จ
- `fully_trusted`: ๋ณด์ ์ ํ ์์. ์์ ํ ์ ๋ขฐํ ์ ์๋ ์์นด์ด๋ธ์์๋ง ์ฌ์ฉ
## Python API
### TzstArchive ํด๋์ค
```python
from tzst import TzstArchive
# ์ ์์นด์ด๋ธ ์์ฑ
with TzstArchive("archive.tzst", "w", compression_level=5) as archive:
archive.add("file.txt")
archive.add("directory/", recursive=True)
# ๊ธฐ์กด ์์นด์ด๋ธ ์ฝ๊ธฐ
with TzstArchive("archive.tzst", "r") as archive:
# ๋ด์ฉ ๋ชฉ๋ก
contents = archive.list(verbose=True)
# ๋ณด์ ํํฐ ์ ์ฉ ์ถ์ถ
archive.extract("file.txt", "output/", filter="data")
# ๋ฌด๊ฒฐ์ฑ ํ
์คํธ
is_valid = archive.test()
# ๋์ฉ๋ ์์นด์ด๋ธ์ ์คํธ๋ฆฌ๋ฐ ๋ชจ๋ ์ฌ์ฉ
with TzstArchive("large_archive.tzst", "r", streaming=True) as archive:
archive.extract(path="output/")
```
**์ค์ํ ์ ํ ์ฌํญ:**
- **์ถ๊ฐ ๋ชจ๋ ๋ฏธ์ง์**: ์ฌ๋ฌ ์์นด์ด๋ธ ์์ฑ ๋๋ ์ ์ฒด ์์นด์ด๋ธ ์ฌ์์ฑ ํ์
### ํธ์ ํจ์
#### create_archive()
```python
from tzst import create_archive
# ์์์ ์์
์ผ๋ก ์์ฑ (๊ธฐ๋ณธ๊ฐ)
create_archive(
archive_path="backup.tzst",
files=["documents/", "photos/", "config.txt"],
compression_level=10
)
```
#### extract_archive()
```python
from tzst import extract_archive
# ๋ณด์ ์ถ์ถ (๊ธฐ๋ณธ๊ฐ: 'data' ํํฐ)
extract_archive("backup.tzst", "restore/")
# ํน์ ํ์ผ ์ถ์ถ
extract_archive("backup.tzst", "restore/", members=["config.txt"])
# ๋๋ ํฐ๋ฆฌ ๊ตฌ์กฐ ํํํ
extract_archive("backup.tzst", "restore/", flatten=True)
# ๋์ฉ๋ ์์นด์ด๋ธ์ ์คํธ๋ฆฌ๋ฐ ์ฌ์ฉ
extract_archive("large_backup.tzst", "restore/", streaming=True)
```
#### list_archive()
```python
from tzst import list_archive
# ๊ฐ๋จํ ๋ชฉ๋ก
files = list_archive("backup.tzst")
# ์์ธ ๋ชฉ๋ก
files = list_archive("backup.tzst", verbose=True)
# ๋์ฉ๋ ์์นด์ด๋ธ์ ์คํธ๋ฆฌ๋ฐ ์ฌ์ฉ
files = list_archive("large_backup.tzst", streaming=True)
```
#### test_archive()
```python
from tzst import test_archive
# ๊ธฐ๋ณธ ๋ฌด๊ฒฐ์ฑ ํ
์คํธ
if test_archive("backup.tzst"):
print("์์นด์ด๋ธ๊ฐ ์ ํจํฉ๋๋ค")
# ์คํธ๋ฆฌ๋ฐ์ผ๋ก ํ
์คํธ
if test_archive("large_backup.tzst", streaming=True):
print("๋์ฉ๋ ์์นด์ด๋ธ๊ฐ ์ ํจํฉ๋๋ค")
```
## ๊ณ ๊ธ ๊ธฐ๋ฅ
### ํ์ผ ํ์ฅ์
๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ์ง๋ฅ์ ์ธ ์ ๊ทํ๋ก ํ์ผ ํ์ฅ์๋ฅผ ์๋ ์ฒ๋ฆฌํฉ๋๋ค:
- `.tzst` - tar+zstandard ์์นด์ด๋ธ์ ๊ธฐ๋ณธ ํ์ฅ์
- `.tar.zst` - ๋์ฒด ํ์ค ํ์ฅ์
- ๊ธฐ์กด ์์นด์ด๋ธ ์ด ๋ ์๋ ๊ฐ์ง
- ์์นด์ด๋ธ ์์ฑ ์ ์๋ ํ์ฅ์ ์ถ๊ฐ
```python
# ๋ชจ๋ ์ ํจํ ์์นด์ด๋ธ ์์ฑ
create_archive("backup.tzst", files) # backup.tzst ์์ฑ
create_archive("backup.tar.zst", files) # backup.tar.zst ์์ฑ
create_archive("backup", files) # backup.tzst ์์ฑ
create_archive("backup.txt", files) # backup.tzst ์์ฑ (์ ๊ทํ๋จ)
```
### ์์ถ ๋ ๋ฒจ
Zstandard ์์ถ ๋ ๋ฒจ ๋ฒ์: 1 (๊ฐ์ฅ ๋น ๋ฆ) ~ 22 (์ต๋ ์์ถ):
- **๋ ๋ฒจ 1-3**: ๋น ๋ฅธ ์์ถ, ํ์ผ ํฌ๊ธฐ ํผ
- **๋ ๋ฒจ 3** (๊ธฐ๋ณธ๊ฐ): ์๋์ ์์ถ๋ฅ ์ ๊ท ํ
- **๋ ๋ฒจ 10-15**: ๋ ๋์ ์์ถ, ๋๋ฆผ
- **๋ ๋ฒจ 20-22**: ์ต๋ ์์ถ, ๋งค์ฐ ๋๋ฆผ
### ์คํธ๋ฆฌ๋ฐ ๋ชจ๋
๋์ฉ๋ ์์นด์ด๋ธ์ ๋ฉ๋ชจ๋ฆฌ ํจ์จ์ ์ฒ๋ฆฌ๋ฅผ ์ํด ์คํธ๋ฆฌ๋ฐ ๋ชจ๋ ์ฌ์ฉ:
**์ฅ์ :**
- ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋ ํ์ ํ ๊ฐ์
- ๋ฉ๋ชจ๋ฆฌ์ ๋ง์ง ์๋ ๋์ฉ๋ ์์นด์ด๋ธ ์ฒ๋ฆฌ ์ฑ๋ฅ ํฅ์
- ๋ฆฌ์์ค ์๋ ์ ๋ฆฌ
**์ฌ์ฉ ์๊ธฐ:**
- 100MB ์ด์์ ์์นด์ด๋ธ
- ๋ฉ๋ชจ๋ฆฌ๊ฐ ์ ํ๋ ํ๊ฒฝ
- ๋์ฉ๋ ํ์ผ์ด ๋ง์ ์์นด์ด๋ธ ์ฒ๋ฆฌ
```python
# ์์ : ๋์ฉ๋ ๋ฐฑ์
์์นด์ด๋ธ ์ฒ๋ฆฌ
from tzst import extract_archive, list_archive, test_archive
large_archive = "backup_500gb.tzst"
# ๋ฉ๋ชจ๋ฆฌ ํจ์จ์ ์์
is_valid = test_archive(large_archive, streaming=True)
contents = list_archive(large_archive, streaming=True, verbose=True)
extract_archive(large_archive, "restore/", streaming=True)
```
### ์์์ ์์
๋ชจ๋ ํ์ผ ์์ฑ ์์
์ ๊ธฐ๋ณธ์ ์ผ๋ก ์์์ ํ์ผ ์์
์ ์ฌ์ฉํฉ๋๋ค:
- ์์ ํ์ผ์ ๋จผ์ ์์ฑ ํ ์์์ ์ด๋
- ํ๋ก์ธ์ค ์ค๋จ ์ ์๋ ์ ๋ฆฌ
- ์์๋๊ฑฐ๋ ๋ถ์์ ํ ์์นด์ด๋ธ ์ํ ์์
- ํฌ๋ก์ค ํ๋ซํผ ํธํ์ฑ
```python
# ๊ธฐ๋ณธ์ ์ผ๋ก ์์์ ์์
ํ์ฑํ
create_archive("important.tzst", files) # ์ค๋จ์ผ๋ก๋ถํฐ ์์
# ํ์ํ ๊ฒฝ์ฐ ๋นํ์ฑํ ๊ฐ๋ฅ (๊ถ์ฅํ์ง ์์)
create_archive("test.tzst", files, use_temp_file=False)
```
### ์ค๋ฅ ์ฒ๋ฆฌ
```python
from tzst import TzstArchive
from tzst.exceptions import (
TzstError,
TzstArchiveError,
TzstCompressionError,
TzstDecompressionError,
TzstFileNotFoundError
)
try:
with TzstArchive("archive.tzst", "r") as archive:
archive.extract()
except TzstDecompressionError:
print("์์นด์ด๋ธ ์์ถ ํด์ ์คํจ")
except TzstFileNotFoundError:
print("์์นด์ด๋ธ ํ์ผ์ ์ฐพ์ ์ ์์")
except KeyboardInterrupt:
print("์ฌ์ฉ์์ ์ํด ์์
์ค๋จ๋จ")
# ์๋์ผ๋ก ์ ๋ฆฌ๋จ
```
## ์ฑ๋ฅ ๋ฐ ๋น๊ต
### ์ฑ๋ฅ ํ
1. **์์ถ ๋ ๋ฒจ**: ๋๋ถ๋ถ์ ๊ฒฝ์ฐ ๋ ๋ฒจ 3์ด ์ต์
2. **์คํธ๋ฆฌ๋ฐ**: 100MB ์ด์ ์์นด์ด๋ธ์ ์ฌ์ฉ
3. **์ผ๊ด ์์
**: ๋จ์ผ ์ธ์
์์ ์ฌ๋ฌ ํ์ผ ์ถ๊ฐ
4. **ํ์ผ ์ ํ**: ์ด๋ฏธ ์์ถ๋ ํ์ผ์ ์ถ๊ฐ ์์ถ์ด ๊ฑฐ์ ์๋จ
### ๋ค๋ฅธ ๋๊ตฌ์ ๋น๊ต
**vs tar + gzip:**
- ๋ ๋์ ์์ถ๋ฅ
- ๋ ๋น ๋ฅธ ์์ถ ํด์
- ํ๋์ ์ธ ์๊ณ ๋ฆฌ์ฆ
**vs tar + xz:**
- ํ์ ํ ๋น ๋ฅธ ์์ถ
- ์ ์ฌํ ์์ถ๋ฅ
- ๋ ๋์ ์๋/์์ถ๋ฅ ๊ท ํ
**vs zip:**
- ๋ ๋์ ์์ถ
- Unix ๊ถํ ๋ฐ ๋ฉํ๋ฐ์ดํฐ ๋ณด์กด
- ๋ ๋์ ์คํธ๋ฆฌ๋ฐ ์ง์
## ์๊ตฌ ์ฌํญ
- Python 3.12 ์ด์
- zstandard >= 0.19.0
## ๊ฐ๋ฐ
### ๊ฐ๋ฐ ํ๊ฒฝ ์ค์
์ต์ Python ํจํค์ง ํ์ค ์ฌ์ฉ:
```bash
git clone https://github.com/xixu-me/tzst.git
cd tzst
pip install -e .[dev]
```
### ํ
์คํธ ์คํ
```bash
# ์ปค๋ฒ๋ฆฌ์ง ํฌํจ ํ
์คํธ ์คํ
pytest --cov=tzst --cov-report=html
# ๋๋ ๊ฐ๋จํ ๋ช
๋ น์ด ์ฌ์ฉ (์ปค๋ฒ๋ฆฌ์ง ์ค์ ์ pyproject.toml์ ์์)
pytest
```
### ์ฝ๋ ํ์ง
```bash
# ์ฝ๋ ํ์ง ํ์ธ
ruff check src tests
# ์ฝ๋ ํฌ๋งทํ
ruff format src tests
```
## ๊ธฐ์ฌ
๊ธฐ์ฌ๋ฅผ ํ์ํฉ๋๋ค! ๋ค์ ์ฌํญ์ ์ํด [๊ธฐ์ฌ ๊ฐ์ด๋](CONTRIBUTING.md)๋ฅผ ์ฝ์ด์ฃผ์ธ์:
- ๊ฐ๋ฐ ์ค์ ๋ฐ ํ๋ก์ ํธ ๊ตฌ์กฐ
- ์ฝ๋ ์คํ์ผ ๊ฐ์ด๋๋ผ์ธ ๋ฐ ๋ชจ๋ฒ ์ฌ๋ก
- ํ
์คํธ ์๊ตฌ ์ฌํญ ๋ฐ ํ
์คํธ ์์ฑ ๋ฐฉ๋ฒ
- ํ ๋ฆฌํ์คํธ ํ๋ก์ธ์ค ๋ฐ ๋ฆฌ๋ทฐ ์ํฌํ๋ก
### ๊ธฐ์ฌ์ ๋น ๋ฅธ ์์
```bash
git clone https://github.com/xixu-me/tzst.git
cd tzst
pip install -e .[dev]
python -m pytest tests/
```
### ํ์ํ๋ ๊ธฐ์ฌ ์ ํ
- **๋ฒ๊ทธ ์์ ** - ๊ธฐ์กด ๊ธฐ๋ฅ์ ๋ฌธ์ ํด๊ฒฐ
- **๊ธฐ๋ฅ** - ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ์๋ก์ด ๊ธฐ๋ฅ ์ถ๊ฐ
- **๋ฌธ์** - ๋ฌธ์ ๊ฐ์ ๋๋ ์ถ๊ฐ
- **ํ
์คํธ** - ํ
์คํธ ์ปค๋ฒ๋ฆฌ์ง ์ถ๊ฐ ๋๋ ๊ฐ์
- **์ฑ๋ฅ** - ๊ธฐ์กด ์ฝ๋ ์ต์ ํ
- **๋ณด์** - ๋ณด์ ์ทจ์ฝ์ ํด๊ฒฐ
## ๊ฐ์ฌ์ ๋ง
- ์ฐ์ํ ์์ถ ์๊ณ ๋ฆฌ์ฆ์ ์ ๊ณตํ [Meta Zstandard](https://github.com/facebook/zstd)
- Python ๋ฐ์ธ๋ฉ์ ์ ๊ณตํ [python-zstandard](https://github.com/indygreg/python-zstandard)
- ์๊ฐ๊ณผ ํผ๋๋ฐฑ์ ์ค Python ์ปค๋ฎค๋ํฐ
## ๋ผ์ด์ ์ค
์ ์๊ถ © [์ ์ฌ](https://xi-xu.me). ๋ชจ๋ ๊ถ๋ฆฌ ๋ณด์ .
[BSD 3-Clause](LICENSE) ๋ผ์ด์ ์ค๋ก ์ฌ์ฉ์ด ํ๊ฐ๋์์ต๋๋ค.