Можно ли читать и добавлять в tar файл с Python tarfile - PullRequest
1 голос
/ 02 апреля 2020

Я пытаюсь прочитать файл tar, идентифицировать некоторые файлы, прочитать их, а затем записать новый файл в тот же файл с помощью Python. Похоже, extractfile () разрешен только если режим "r". Это тот случай? Есть ли способ извлекать файлы из tar в памяти, а также добавлять новые файлы в tar одновременно? Пример кода ниже:

def genEntry(tar, tarinfo, source):
    heading = re.compile(r'#+(\s+)?')
    f = tar.extractfile(tarinfo)
    f.seek(0)
    while True:
        line = f.readline().decode()
        print(line)
        if not line:
            break
        print(line)
        if heading.match(line):
            title = heading.sub('',line).replace('\n','')
            return[tarinfo.name.replace(source,'.'), title]
    return [tarinfo.name.replace(source,'.'), tarinfo.name.replace(source,'')]

with tarfile.open(args.source, mode='a') as tar:
  source = 'somepath'
  subDir = 'someSubDir'
  path = '/'.join((source, subDir))
  if tar.getmember(path):
    pathre = re.compile(r'{}\/.+?\/readme\.md'.format(re.escape(path)), re.IGNORECASE)
      for tarinfo in tar.getmembers():
        if re.search(pathre, tarinfo.name):
          genEntry(tar, tarinfo, source)
...

Это приведет к следующей ошибке:

OSError: неправильная операция для режима 'a'

1 Ответ

1 голос
/ 17 апреля 2020

Насколько я могу судить, невозможно прочитать и добавить в файл за один проход. Хотя в конечном итоге я пошел в направлении облегчения потоковой передачи tar-файла в и из моего Python сценария, я определил двухпроходное решение для чтения / записи для моего вопроса выше.

Вот по сути подход, который я получил вкл.

    files = []
    with tarfile.open(tarpath) as tar:
        files= readTar(tar)
    with tarfile.open(tarpath, mode='a') as tar:
        for fileobj in files:
            writeFile(tar, fileobj[0], fileobj[1])

def readTar(tar):
# Your your logic to build the files you want to build in the amended file here

def writeFile(tar, tarinfo, payload):
    if len(payload) != 0:
        data = payload.encode('utf8')
        tarinfo.mode = 0o444
        tarinfo.size = len(data)
        tar.addfile(tarinfo, fileobj=BytesIO(data))
        return tar
...