레이블이 py7zr인 게시물을 표시합니다. 모든 게시물 표시
레이블이 py7zr인 게시물을 표시합니다. 모든 게시물 표시

2022년 9월 17일 토요일

py7zr multi volume(python 7z 멀티 볼륨(분할) 압축 사용) 2탄

 

7z 멀티 볼륨 처리하는 부분 업데이트를 했습니다.

기존 글은 아래 링크로 읽어주시기 바랍니다. 

https://swlock.blogspot.com/2022/06/py7zr-multi-volumepython-7z.html


압축 파일의 파일 경로 포함됨

기존 예제의 문제점 압축 파일에 경로명까지 포함되는 문제가 있습니다.

압축을 풀게되면 경로가 복잡한 경우 복잡한 경로 아래에 풀리게 됩니다.

# 기본 압축 : 경로 저장 안함
outfile = "out/output4.7z" # 압축된 결과 파일
with multivolumefile.open(outfile, mode='wb', volume=1023) as target_archive:
with py7zr.SevenZipFile(target_archive, 'w') as archive:
archive.write(orifile, arcname="a.bin")

for fileinfo in target_archive._fileinfo:
print(fileinfo.filename)

# out\output4.7z.0001
# out\output4.7z.0002

writeall -> write 함수로 바꾸고, arcname 인자 사용하였습니다.


멀티 볼륨 파일 목록 시점 문제

다른 하나의 문제점은 멀티 볼륨으로 생성된 파일들을 그때 그때마다 처리를 했었는데요. 실제 프로젝트에서 사용해보니 file이 제대로 생성 안되는 flush 문제가 발생하는 듯 했습니다.

그래서 멀티 볼륨된 파일들을 처리하기 위해서는 아래 예제처럼 모두 생성된 후 이용하도록 해야합니다.

zfilelist = [] # 파일 목록을 저장하는 변수
# 압축 안함 FILTER_COPY
with multivolumefile.open(outfile, mode='wb', volume=1023) as target_archive:
with py7zr.SevenZipFile(target_archive, 'w', filters=filters) as archive:
archive.writeall(orifile)

for fileinfo in target_archive._fileinfo:
zfilelist.append(fileinfo.filename)

# 파일 이름을 처리할때는 모두 완료된후 아래와 같은 형태로 처리 하도록 합니다.
for filename in zfilelist:
print(filename)


두 가지 예제를 추가한 새로운 코드를 공개합니다.

sourcecode/7z_vol_make_archive.py at main · donarts/sourcecode · GitHub


2022년 6월 11일 토요일

py7zr multi volume(python 7z 멀티 볼륨(분할) 압축 사용)

 py7zr

python의 7z을 사용할 수 있는 패키지 입니다.

압축 해제가 예제들은 많이 있는데 멀티 볼륨에 대한 압축 방법 설명이 미흡해서 찾아봤습니다.


예제

import py7zr # pip install py7zr
import multivolumefile # pip install multivolumefile
import random
import os

# https://py7zr.readthedocs.io/en/latest/user_guide.html
# https://py7zr.readthedocs.io/en/latest/api.html

def make_random_file(file_name,file_size):
    f = open(file_name, "wb")
    for i in range(int(file_size/2)):
        random_v = random.random()
        random_v = (random_v * 65536) % 65536
        random_v = int(random_v)
        f.write(random_v.to_bytes(2, 'big'))
    f.close()

orifile = "test.bin" # 압축 하려고 하는 파일
outfile = "out/output1.7z" # 압축된 결과 파일

try:
	os.mkdir("out")
except:
	pass

# 임시 파일
make_random_file(orifile,3*1024) 

filters=[{'id':py7zr.FILTER_COPY}]
'''
LZMA2 + Delta
[{'id': FILTER_DELTA}, {'id': FILTER_LZMA2, 'preset': PRESET_DEFAULT}]

LZMA2 + BCJ
[{'id': FILTER_X86}, {'id': FILTER_LZMA2, 'preset': PRESET_DEFAULT}]

LZMA2 + ARM
[{'id': FILTER_ARM}, {'id': FILTER_LZMA2, 'preset': PRESET_DEFAULT}]

LZMA + BCJ
[{'id': FILTER_X86}, {'id': FILTER_LZMA}]

LZMA2
[{'id': FILTER_LZMA2, 'preset': PRESET_DEFAULT}]

LZMA
[{'id': FILTER_LZMA}]

BZip2
[{'id': FILTER_BZIP2}]

Deflate
[{'id': FILTER_DEFLATE}]

ZStandard
[{'id': FILTER_ZSTD, 'level': 3}]

PPMd
[{'id': FILTER_PPMD, 'order': 6, 'mem': 24}]

[{'id': FILTER_PPMD, 'order': 6, 'mem': "16m"}]

Brolti
[{'id': FILTER_BROTLI, 'level': 11}]

7zAES + LZMA2 + Delta
[{'id': FILTER_DELTA}, {'id': FILTER_LZMA2, 'preset': PRESET_DEFAULT}, {'id': FILTER_CRYPTO_AES256_SHA256}]

7zAES + LZMA2 + BCJ
[{'id': FILTER_X86}, {'id': FILTER_LZMA2, 'preset': PRESET_DEFAULT}, {'id': FILTER_CRYPTO_AES256_SHA256}]

7zAES + LZMA
[{'id': FILTER_LZMA}, {'id': FILTER_CRYPTO_AES256_SHA256}]

7zAES + Deflate
[{'id': FILTER_DEFLATE}, {'id': FILTER_CRYPTO_AES256_SHA256}]

7zAES + BZip2
[{'id': FILTER_BZIP2}, {'id': FILTER_CRYPTO_AES256_SHA256}]

7zAES + ZStandard
[{'id': FILTER_ZSTD}, {'id': FILTER_CRYPTO_AES256_SHA256}]
'''
# 분할 압축
with multivolumefile.open(outfile, mode='wb', volume=1023) as target_archive:
    with py7zr.SevenZipFile(target_archive, 'w', filters=filters) as archive:
        archive.writeall(orifile)

    for fileinfo in target_archive._fileinfo:
        print(fileinfo.filename) # 압축한 파일 이름을 알 수 있음


outfile = "out/output2.7z" # 압축된 결과 파일

# 분할 압축
with multivolumefile.open(outfile, mode='wb', volume=1023) as target_archive:
    with py7zr.SevenZipFile(target_archive, 'w') as archive:
        archive.writeall(orifile)

    for fileinfo in target_archive._fileinfo:
        print(fileinfo.filename) # 압축한 파일 이름을 알 수 있음


예제 설명

임시 파일을 만들고 멀티 볼륨으로 압축하는 예제입니다. 여기에서는 알고리즘 선택을 압축 안함과 기본값으로 하는 두가지 예제입니다.

압축 안함의 경우 filters 값을 COPY로 설정하면 됩니다.

filters=[{'id':py7zr.FILTER_COPY}]

filters 인자를 넘기지 않으면 기본값 상태로 압축을 하게됩니다.

일부 코드 에서는 volume_size로 입력하는곳이 있는데 에러가 발생합니다. volume을 사용해주세요


실행결과

out\output1.7z.0001
out\output1.7z.0002
out\output1.7z.0003
out\output1.7z.0004
out\output2.7z.0001
out\output2.7z.0002
out\output2.7z.0003
out\output2.7z.0004