一节 ://www.greenteapress.com/thinkpython/"rel =“nofollow noreferrer”>这本大概是准确的书,

  

管道的常见用途是阅读a   压缩文件递增;那   是,没有解压缩整体   事情一下子。以下功能   将压缩文件的名称作为   一个参数并返回一个管道   使用gunzip来解压缩   内容:

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

如果你从fp读取一行   时间,你永远不必存储   内存中或未打开的未压缩文件   磁盘。

也许我只是在解释这个错误,但我不知道这是怎么回事。 Python无法通过吐出结果中途暂停gunzip,对吧?我假设在继续输出更多行之前读取输出行之前不会阻塞gunzip,因此一些缓冲区必须捕获所有这些(无论是在Python解释器内还是在OS中,无论是在内存中还是在磁盘上),意思是未压缩文件存储在某处完全...对吗?

有帮助吗?

解决方案

你的假设是错误的。 gunzip不必查看整个文件来解压缩它。阅读解压缩文件格式。有一个目录,其中包含各个组件的偏移量。

可以将文件解压缩。

“未压缩文件存储在某处...正确?”

不一定。不确定你为什么要假装它或你在哪里阅读它。

所有低级I / O调用都可以阻止。 gunzip中的写入 - 写入管道时 - 可以在管道缓冲区已满时阻塞。这就是定义管道的I / O的方式。管道I / O块。

有关详细信息,请查看管道的手册页。

  

如果进程尝试从中读取   空管,然后读(2)将
  阻止,直到数据可用。如果   进程尝试写入
  满管(见下文),然后写(2)   阻止,直到有足够的数据   已从管道中读取以允许   写完成。非阻塞结果   使用fcntl(2)可以实现I / O   F_SETFL操作启用
  O_NONBLOCK打开文件状态标志。

其他提示

这真的来自 gunzip 实现,而不是来自python。 它是用C语言编写的。它可能使用C的 stdio.h 中的 fwrite()来编写它的输出。

libc6 实现我使用自动创建一个输出缓冲区,当它被填充时,阻塞 fwrite()直到它可以写更多。

暂停 gunzip 并不是Python,而是内核在尝试写入时会停止执行 gunzip (使用 write()系统调用)到一个完整的缓冲区。这称为阻止IO 。内核维护一个连接管道两端的内部缓冲区,与写入或读取管道的任何进程中发生的任何缓冲无关。

当从具有空缓冲区的管道读取时,Python将同样阻塞,即当前没有写入 gunzip 的任何数据。

管道可视为生产者 - 消费者问题的解决方案。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top