подпроцесс python с помощью gzip - PullRequest
       0

подпроцесс python с помощью gzip

4 голосов
/ 17 сентября 2011

Я пытаюсь передать данные через подпроцесс, сжать их и записать в файл.Следующие работы.Интересно, можно ли вместо этого использовать нативную библиотеку Python gzip?

fid = gzip.open(self.ipFile, 'rb') # input data
oFid = open(filtSortFile, 'wb') # output file
sort = subprocess.Popen(args="sort | gzip -c ", shell=True, stdin=subprocess.PIPE, stdout=oFid) # set up the pipe
processlines(fid, sort.stdin, filtFid) # pump data into the pipe

ВОПРОС: Как мне сделать это вместо этого ... где используется пакет Python gzip?Мне в основном любопытно узнать, почему следующее дает мне текстовые файлы (вместо сжатой двоичной версии) ... очень странно.

fid = gzip.open(self.ipFile, 'rb')
oFid = gzip.open(filtSortFile, 'wb')
sort = subprocess.Popen(args="sort ", shell=True, stdin=subprocess.PIPE, stdout=oFid)
processlines(fid, sort.stdin, filtFid)

Ответы [ 2 ]

4 голосов
/ 17 сентября 2011

subprocess записывает в oFid.fileno(), но gzip возвращает fd базового файлового объекта :

def fileno(self):
    """Invoke the underlying file object's fileno() method."""
    return self.fileobj.fileno()

Чтобы включить сжатие, используйте gzip методы напрямую:

import gzip
from subprocess import Popen, PIPE
from threading import Thread

def f(input, output):
    for line in iter(input.readline, ''):
        output.write(line)

p = Popen(["sort"], bufsize=-1, stdin=PIPE, stdout=PIPE)
Thread(target=f, args=(p.stdout, gzip.open('out.gz', 'wb'))).start()

for s in "cafebabe":
    p.stdin.write(s+"\n")
p.stdin.close()

Пример

$ python gzip_subprocess.py  && od -c out.gz && zcat out.gz 
0000000 037 213  \b  \b 251   E   t   N 002 377   o   u   t  \0   K 344
0000020   J 344   J 002 302   d 256   T       L 343 002  \0   j 017   j
0000040   k 020  \0  \0  \0
0000045
a
a
b
b
c
e
e
f
2 голосов
/ 17 сентября 2011

Поскольку вы просто указываете дескриптор файла, который нужно передать процессу, который вы выполняете, больше нет методов, задействованных в объекте файла.Чтобы обойти это, вы можете записать свой вывод в канал и прочитать из него примерно так:

oFid = gzip.open(filtSortFile, 'wb')
sort = subprocess.Popen(args="sort ", shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
oFid.writelines(sort.stdout)
oFid.close()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...