LINUX.ORG.RU

А как в питоне пайпать?

 


0

2

Есть tarfile, есть pgzip, но он работает со строками. У меня нет возможности сохранять промежуточный tar, как я могу сразу сжимать tar, а потом скармливать его другому модулю? Возможно ли это? Видал способ с BytesIO(), но он делает это в оперативке как я понял, а это больно жирно.


Ответ на: комментарий от Aswed

Because the module uses /bin/sh command lines, a POSIX or compatible shell for os.system() and os.popen() is required.

А это точно оно? Я может объяснил криво.. Короче, я пытаюсь ужать 500 гигов и не могу хранить огромный тар на диске. Как мне начать сжимать его другой функцией по мере его создания, как я делал бы в баше, вызывая команды подобно tar -cf - ./shit | gz -c > out.tar.gz?

u0000
() автор топика

Аа у тебя питоновский tarfile. Я не уверен, что он вообще поддерживает вывод стримом. А почему собсна ты не можешь использовать файл? Если просто не хочешь срать в системе, есть tempfile.

Aswed ★★★★★
()
Ответ на: комментарий от Aswed

Потому что там данных пол терабайта, это дорого.

u0000
() автор топика
Ответ на: комментарий от u0000

Ясно. Просто сделай вызовы tar и gz через pipes, ну или сделай в своем скрипте os.system("tar -cf - ./shit | gz -c > out.tar.gz"). Ну или через subprocess. Учитывая что tarfile и pgzip на питоне написаны, 500 гигов он тебе может оч долго паковать.

Aswed ★★★★★
()
Ответ на: комментарий от u0000

если скрипт не планируется размножать на винду, то никакой это не костыль, а нормальный системный метод

flant ★★★★
()
Ответ на: комментарий от utf8nowhere

Пришёл знающий человек и всё опошлил свел к проблеме XY. Нет бы злобно понаблюдать за попытками удаления гландов через жопу.

token_polyak ★★★★★
()
Последнее исправление: token_polyak (всего исправлений: 2)
Ответ на: комментарий от u0000

https://github.com/python/cpython/blob/0dfbb769df9e492a08b55ba59bf256b900b43296/Lib/tarfile.py#L328-L332:

class _Stream:
   """Class that serves as an adapter between TarFile and
      a stream-like object.  The stream-like object only
      needs to have a read() or write() method and is accessed
      blockwise.  Use of gzip or bzip2 compression is possible.

Написано, что только метода write хватит, если ты используешь запись в поток (mode='w|', в предыдущем сообщении забыл mode=).

#!/usr/bin/env python3
import tarfile

class FileLike:
	def write(self, bytes):
		print(type(bytes), len(bytes))

with tarfile.open(mode='w|', fileobj=FileLike()) as tf:
	tf.add('tarfile.pgzip.py') # имя этого скрипта

Выводит

<class 'bytes'> 10240

(Ну и если добавить print(bytes), в выводе можно найти содержимое скрипта).

Буфер, есс-но, можно увеличить, т.к. параллелить сжатие 10КБ бессмысленно.

utf8nowhere ★★★
()
Ответ на: комментарий от u0000

Короче, даже классов-обёрток никаких не надо

#!/usr/bin/env python3
import pgzip
import tarfile

with pgzip.open('out.tgz', 'wb') as fw, tarfile.open(mode='w|', fileobj=fw) as tf:
	tf.add(__file__)
utf8nowhere ★★★
()
Ответ на: комментарий от utf8nowhere

Ого, ого. Обязательно утром попробую в деле. Всю голову себе сломал как правильно. Если буду в ДС2, то с меня пиво!

u0000
() автор топика
Ответ на: комментарий от u0000

А можно вопрос? Почему собсна тебя такое решение устраивает, а внешний вызов tar + gz или tar cvfz нет? Ну прост сишный архиватор будет работать значительно быстрее чем pure python имплементания zip алгоритма. Учитывая, что данных у тебя пол терабайта, это должно быть весомо. Можно было бы хотя бы zlib взять, он сишный. Если тебя deflate алгоритм интересует.

Aswed ★★★★★
()
Ответ на: комментарий от Aswed

pure python имплементания zip алгоритма

Можно было бы хотя бы zlib взять, он сишный

$ grep zlib ~/.local/lib/python3.10/site-packages/pgzip/pgzip.py
import zlib
            self.compress = zlib.compressobj(
                compresslevel, zlib.DEFLATED, -zlib.MAX_WBITS, zlib.DEF_MEM_LEVEL, 0
        Compress data with zlib deflate algorithm.
        cpr = zlib.compressobj(
            zlib.DEFLATED,
            -zlib.MAX_WBITS,
            9,  # use memory level 9 > zlib.DEF_MEM_LEVEL (8) for better performance
            crc = zlib.crc32(data, zlib.crc32(pdata))
            crc = zlib.crc32(data)
        dpr = zlib.decompressobj(wbits=-zlib.MAX_WBITS)
        crc = zlib.crc32(body_bytes)
            crc = zlib.crc32(dpr.unconsumed_tail, crc)
utf8nowhere ★★★
()
Последнее исправление: utf8nowhere (всего исправлений: 2)
Ответ на: комментарий от I-Love-Microsoft

Во-первых, нет, а в-нулевых я показал минимально рабочий код, менять размеры буферов и проч. тюнинг предполагается делать самому.

utf8nowhere ★★★
()
Последнее исправление: utf8nowhere (всего исправлений: 1)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.