Каналы Python - Что происходит при пошаговом чтении выходных данных

StackOverflow https://stackoverflow.com/questions/1612349

  •  06-07-2019
  •  | 
  •  

Вопрос

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

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

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

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

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

Это было полезно?

Решение

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

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

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

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

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

Подробности смотрите в man-страницах для pipe.

  

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

Другие советы

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

Реализация

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top