내 경우 큰 파일은 myBigFile.tar.gz
크기가 52GB인 tar.gz였으며 이를 2GB 크기의 청크로 분할하여 27개의 부분 파일을 갖게 되었습니다.
제가 처음부터 작성한 코드는 다음과 같습니다.
from time import sleep
from glob import glob
import filecmp
import os
CHUNK_SIZE = 2097152000 # bytes
# CHUNK_SIZE = 1000000 # bytes
# CHUNK_SIZE = 2 # bytes
ORIGINAL_FILE_DIR = './data/original'
SPLITTED_FILE_DIR = './data/splitted'
JOINED_FILE_DIR = './data/joined'
def get_original_filepath(filename):
return f'{ORIGINAL_FILE_DIR}/{filename}'
def get_splitted_filepath(filename, overwrite=False):
partspath = f'{SPLITTED_FILE_DIR}/{filename}.parts'
if overwrite:
try:
os.rmdir(partspath)
except Exception as e:
print(e)
try:
os.mkdir(partspath)
except Exception as e:
print(e)
return partspath
def get_joined_filepath(filename):
return f'{JOINED_FILE_DIR}/{filename}'
def get_part_extension(part, pad_num=8):
if isinstance(part, int):
return f'{part:0{pad_num}d}.part'
elif isinstance(part, str):
return f'{part}.part'
else:
raise Exception('Unknown typeof <part>', type(part))
def get_part_filename(filename, part, pad_num=8):
part_extension = get_part_extension(part, pad_num)
return f'{filename}.{part_extension}'
def get_file_size(filepath):
return os.path.getsize(filepath)
def get_number_of_chunks(total_size, chunk_size):
return total_size // chunk_size + (total_size % chunk_size > 0)
def is_directory_empty(directory_path):
try:
# Get the list of files and directories in the specified path
files = os.listdir(directory_path)
# Check if there are any files in the list
if len(files) == 0:
return True
else:
return False
except:
# Handle the case when the directory does not exist
return True
def split_file(filename, chunk_size=CHUNK_SIZE):
original_path = get_original_filepath(filename)
if get_file_size(original_path) == 0:
print(Exception('E: Original file not found!'))
splitted_path = get_splitted_filepath(filename, overwrite=True)
with open(original_path, 'rb') as readfile:
number_of_chunks = get_number_of_chunks(get_file_size(original_path),
chunk_size)
for part in range(number_of_chunks):
chunk = readfile.read(chunk_size)
part_filename = get_part_filename(filename, part,
len(str(number_of_chunks)))
with open(f'{splitted_path}/{part_filename}', 'wb') as writefile:
writefile.write(chunk)
def join_file(filename):
splitted_path = get_splitted_filepath(filename)
joined_path = get_joined_filepath(filename)
if is_directory_empty(splitted_path):
print(Exception('E: Splitted file not found!'))
part = '*' # wilcard
part_filename = get_part_filename(filename, part)
partfiles = [
os.path.normpath(fn) for fn in glob(f'{splitted_path}/{part_filename}')
]
with open(joined_path, 'ab') as appendfile:
for partfile in partfiles:
with open(partfile, 'rb') as readfile:
appendfile.write(readfile.read())
def compare_file(filename):
# Specify the paths of the two files
file1_path = get_original_filepath(filename)
file2_path = get_joined_filepath(filename)
return f'{filename} is identical.' if filecmp.cmp(
file1_path, file2_path) else f'{filename} is not identical.'
filename = 'myBigFile.tar.gz'
split_file(filename)
join_file(filename)
print(compare_file(filename))
따라서 Splitted_path는 다음과 같습니다.
./data/myBigFile.tar.gz.parts/myBigFile.tar.gz.00.part
./data/myBigFile.tar.gz.parts/myBigFile.tar.gz.01.part
...
./data/myBigFile.tar.gz.parts/myBigFile.tar.gz.25.part
tar, zip 또는 기타 아카이버와 같은 Unix 유틸리티를 사용할 수 있다는 것을 알고 있습니다.
CHUNK_SIZE가 작은 작은 파일에서도 테스트했는데 문제 없이 파일에 결합되었습니다.
답변1
임의의 바이트 지점에서 바이너리 파일을 분할할 수 있습니다.
텍스트 파일을 분할하는 경우 임의의 바이트 지점에서 분할할 수 있지만 멀티바이트 유니코드 문자 중간에서 분할될 가능성이 높습니다. 그러나 내용을 해석하기 전에 파일을 연결하면 문제가 되지 않습니다. (또한 내용을 처리하기 전에 바이너리의 일부를 연결해야 하므로 차이가 없습니다.)
Python 코드에서와 같이 가변 비트 출력 조각을 사용한다는 것은 cat myBigFile.tar.gz.*.part
간단한 콘텐츠를 사용하여 원본 콘텐츠를 재구성할 수 없다는 것을 의미합니다. (26개 부품의 경우 1, 10, 11, 12… 19, 2, 20, 21… 26, 3, 4, 5, 6, 7, 8, 9의 순서로 표시됩니다.)
다음은 myBigFile.tar.gz
사용자 고유의 명명 규칙을 사용하여 2GB 부분으로 분할하는 방법입니다.
split --bytes=2G --numeric-suffixes=1 --suffix-length=2 --additional-suffix=.part myBigFile.tar.gz myBigFile.tar.gz.
man split
명령줄 스위치에 대한 자세한 내용은 리소스를 참조하세요.
출력 파일 예:
myBigFile.tar.gz.01.part
myBigFile.tar.gz.02.part
myBigFile.tar.gz.03.part
…
이러한 파일이 있으면 간단한 명령과 셸 와일드카드를 사용하여 원본 파일을 재구성할 수 있습니다.
cat myBigFile.tar.gz.??.part >myBigFile.tar.gz