Python Pipes - что происходит при чтении вывода - PullRequest
0 голосов
/ 23 октября 2009

Согласно разделу в эта предположительно точная книга ,

Обычное использование труб - читать сжатый файл постепенно; тот есть, не сжимая весь вещь сразу. Следующая функция принимает имя сжатого файла как параметр и возвращает канал, который использует gunzip для распаковки Содержание:

 def open_gunzip(filename):
     cmd = 'gunzip -c ' + filename
     fp = os.popen(cmd)
     return fp

Если вы читаете строки из fp по одному время, вы никогда не должны хранить несжатый файл в памяти или на диск.

Может, я просто неверно истолковываю это, но я не понимаю, как это возможно. У Python не могло быть способа приостановить автоматическую разгрузку на полпути, выплевывая результаты, верно? Я предполагаю, что gunzip не будет блокироваться, пока не будет прочитана строка вывода, прежде чем продолжать выводить больше строк, поэтому некоторый буфер должен захватывать все это (будь то внутри интерпретатора Python или в ОС, в памяти или на диске). ) означает, что несжатый файл хранится где-то в полном объеме ... верно?

Ответы [ 3 ]

2 голосов
/ 23 октября 2009

Ваше предположение неверно. gunzip не должен видеть весь файл, чтобы распаковать его. Прочитайте формат файла распаковки. Там есть каталог со смещениями для отдельных компонентов.

Возможно распаковать файл по частям.

"Несжатый файл хранится где-то полностью ... верно?"

Не обязательно. Не уверен, почему ты это предполагаешь или где читаешь.

Все низкоуровневые вызовы ввода / вывода могут блокироваться. Запись в gunzip - при записи в канал - может блокироваться, когда буфер канала заполнен. Так определяется ввод / вывод в канал. Трубные блоки ввода / вывода.

Проверьте man-страницы для трубы для деталей.

Если процесс пытается прочитать из пустая труба, затем читать (2) будет
блокировать, пока данные не доступны. Если процесс пытается записать в
полная труба (см. ниже), затем напишите (2) блоки до достаточного количества данных
был прочитан из трубы, чтобы позволить написать для завершения. Неблокируемая
Ввод / вывод возможен при использовании fcntl (2) Операция F_SETFL для включения
O_NONBLOCK флаг состояния открытого файла.

1 голос
/ 23 октября 2009

Это на самом деле происходит от gunzip реализации, а не от Python. Он написан на C. Он, вероятно, использует fwrite() из C stdio.h для записи своего вывода.

libc6 Реализация, которую я использую, автоматически создает выходной буфер, и, когда он заполняется, блокируется на fwrite(), пока он не сможет записать больше.

0 голосов
/ 11 января 2012

Не Python приостанавливает gunzip, это то, что ядро ​​прекратит выполнение gunzip, когда попытается записать (используя системный вызов write()) в полный буфер. Это называется блокировка на IO . Ядро поддерживает внутренний буфер, соединяющий два конца трубопровода, независимо от буферизации, происходящей в любых процессах, которые записывают или читают из канала.

Python будет аналогичным образом блокироваться при чтении из канала с пустым буфером, то есть в который в настоящее время не записаны данные из gunzip.

Трубы можно рассматривать как решение проблемы Производитель-потребитель .

...