4

Я хотел бы заархивировать пару файлов, которые могут составлять около 99 ГБ, используя python. Каков наиболее эффективный способ сделать это, используя библиотеку zipfile. Это пример кода, у меня естьКак зашифровать очень большой файл в python

with gcs.open(zip_file_name, 'w', content_type=b'application/zip') as f: 

    with zipfile.ZipFile(f, 'w') as z: 

     for file in files: 

      is_owner = (is_page_allowed_to_visitor(page, visitor) or (file.owner_id == visitor.id)) 

      if is_owner: 
       file.show = True 
      elif file.available_from: 
       if file.available_from > datetime.now(): 
        file.show = False 
      elif file.available_to: 
       if file.available_to < datetime.now(): 
        file.show = False 
      else: 
       file.show = True 

      if file.show: 

       file_name = "/%s/%s" % (gcs_store.get_bucket_name(), file.gcs_name) 

       gcs_reader = gcs.open(file_name, 'r') 

       z.writestr('%s-%s' %(file.created_on, file.name), gcs_reader.read()) 

       gcs_reader.close() 

f.close() #closing zip file 

некоторые моменты Примечание:

1) Я использую приложение двигателя Google для размещения файлов, так что я не могу использовать() метод zipfile.write. Я могу получить содержимое файла только в байтах.

Заранее спасибо

+0

IINM вам нужно использовать ZipFile расширение формата ZIP64 для файлов выше 4 Гб. –

+0

@PauloScardine Я ищу альтернативное средство для архивирования файлов без необходимости использовать память, так как у меня не будет около 99 ГБ памяти, лежащей около –

+0

. Проверьте [zipstream] (https://github.com/longaccess/python-zipstream) вместо модуля zipfile по умолчанию. К сожалению, вы не можете установить двоичные модули в GAE. –

ответ

1

Я добавил новый метод к zipfile библиотеке. Эта расширенная библиотека zipfile является открытым исходным кодом и может быть найдена на github (EnhancedZipFile). Я добавил новый метод с вдохновением от метода zipfile.write() и метод zipfile.writestr()

def writebuffered(self, zinfo_or_arcname, file_pointer, file_size, compress_type=None): 
    if not isinstance(zinfo_or_arcname, ZipInfo): 
     zinfo = ZipInfo(filename=zinfo_or_arcname, 
         date_time=time.localtime(time.time())[:6]) 

     zinfo.compress_type = self.compression 
     if zinfo.filename[-1] == '/': 
      zinfo.external_attr = 0o40775 << 16 # drwxrwxr-x 
      zinfo.external_attr |= 0x10   # MS-DOS directory flag 
     else: 
      zinfo.external_attr = 0o600 << 16  # ?rw------- 
    else: 
     zinfo = zinfo_or_arcname 

    zinfo.file_size = file_size   # Uncompressed size 
    zinfo.header_offset = self.fp.tell() # Start of header bytes 
    self._writecheck(zinfo) 
    self._didModify = True 

    fp = file_pointer 
    # Must overwrite CRC and sizes with correct data later 
    zinfo.CRC = CRC = 0 
    zinfo.compress_size = compress_size = 0 
    # Compressed size can be larger than uncompressed size 
    zip64 = self._allowZip64 and \ 
      zinfo.file_size * 1.05 > ZIP64_LIMIT 
    self.fp.write(zinfo.FileHeader(zip64)) 
    if zinfo.compress_type == ZIP_DEFLATED: 
     cmpr = zlib.compressobj(zlib.Z_DEFAULT_COMPRESSION, 
      zlib.DEFLATED, -15) 
    else: 
     cmpr = None 
    file_size = 0 
    while 1: 
     buf = fp.read(1024 * 8) 
     if not buf: 
      break 
     file_size = file_size + len(buf) 
     CRC = crc32(buf, CRC) & 0xffffffff 
     if cmpr: 
      buf = cmpr.compress(buf) 
      compress_size = compress_size + len(buf) 
     self.fp.write(buf) 

    if cmpr: 
     buf = cmpr.flush() 
     compress_size = compress_size + len(buf) 
     self.fp.write(buf) 
     zinfo.compress_size = compress_size 
    else: 
     zinfo.compress_size = file_size 
    zinfo.CRC = CRC 
    zinfo.file_size = file_size 
    if not zip64 and self._allowZip64: 
     if file_size > ZIP64_LIMIT: 
      raise RuntimeError('File size has increased during compressing') 
     if compress_size > ZIP64_LIMIT: 
      raise RuntimeError('Compressed size larger than uncompressed size') 
    # Seek backwards and write file header (which will now include 
    # correct CRC and file sizes) 
    position = self.fp.tell()  # Preserve current position in file 
    self.fp.flush() 
    self.filelist.append(zinfo) 
    self.NameToInfo[zinfo.filename] = zinfo 

Очки отметить

  • Я новичок в Python, так что код, который я написал выше, не может быть очень оптимизировано.
  • Пожалуйста, внести свой вклад в проект на GitHub здесь https://github.com/najela/EnhancedZipFile
Смежные вопросы