通过bashpipe道处理大文件,它缓冲吗?

我需要使用如下的命令:

$ cat large.input.file | process.py > large.output.file 

问题是,这是不是硬盘在读取input文件和写入输出文件之间难以跳跃?

有没有办法告诉bash使用这种types的pipe道时使用大的内存缓冲区?

别担心 操作系统会为你做缓冲,而且通常是非常好的。

这就是说:如果你可以改变process.py你可以实现你自己的缓冲。 如果你不能改变process.py你可以写你自己的buffer.py并像这样使用它。

 $ cat large.input.file | buffer.py | process.py | buffer.py > large.output.file 

读取和写入RAM磁盘可能要容易得多。

操作系统会将输出缓冲到一定的数量,但是如果input和输出文件都在同一个驱动器上,可能仍然会有很多头部翻转,除非process.py自己做了一些缓冲。

你可以用pipe道查看器(pv)代替cat (在大多数标准库中都可以使用,如果它不在你的发行版的repo中,可以很容易地编译),这样可以将它设置为缓冲区(使用-B / --buffer-bytes选项),并显示一个进度条(除非你不要求),如果你的process.py没有输出自己的进度信息,这对于一个长时间的操作可能非常方便。 为了将数据从驱动器上的某个位置传送到同一驱动器上的其他位置,除非整个过程主要受CPU限制,而不受I / O限制,否则可能会产生相当大的差异。

所以对于1Mb的缓冲区你可以这样做:

 pv -B 1m large.input.file | process.py > large.output.file 

我一直使用pv这种事情,虽然主要是为了进度指示器而不是可调整的缓冲区大小。

另一个select是使用更多的“标准”(默认情况下通常是可用的标准,其命令行格式与大多数常用命令有点不同) dd ,尽pipe这没有进度条设施:

 dd if=large.input.file bs=1048576 | process.py > large.output.file 

编辑:PS。 吊坠可能会指出cat是不需要在你的例子中,因为以下将工作得很好,并会更有效率:

 process.py < large.input.file > large.output.file 

有人提到要把cat的不道德呼声称为“人化”,这些人大概不应该受到鼓励。

是不是有一个名为“缓冲区”的旧的unix工具? 这不是今天的caching技术所需要的 – 但它是存在的。

我相信用户所面临的问题是input/输出如何在UNIX / Linux世界中普遍起作用。 每个UNIX / Linux进程一次只能有一个I / O操作挂起。 因此,在例子中的cat命令的情况下,cat命令首先读取一些数据,等待它完成,然后写入数据并等待它完成,然后继续。 在一个进程中没有并发的I / O,因此只在读和写之间使用缓冲来暂时保存一些数据。

为了加快速度,可以将input和输出分解为两个不同的进程:一个读取器进程和一个写入器进程,以及大量共享内存用作两个进程之间的缓冲区。 这导致了人们想要的并发I / O,并且可以加速文件传输过程。

由用户指示的用户程序缓冲区实现了我描述的这种并发方法。 在与磁带驱动器进行备份连接时,我使用了相当大的共享内存缓冲区的缓冲区程序。 这导致挂钟转移时间减less了大约20%。

使用缓冲区程序替代'cat'命令可能会导致一些明显的改进…取决于。

请享用!

尝试使用我刚刚放在一起的这个小Python 2程序:

 #! /usr/bin/python2 # This executable path is Gentoo-specific, you might need to change it yourself import sys; if sys.argv[1].endswith('K'): bytestoread = int(sys.argv[1].translate(None, 'K')) * 1024; elif sys.argv[1].endswith('M'): bytestoread = int(sys.argv[1].translate(None, 'M')) * 1024 * 1024; elif sys.argv[1].endswith('G'): bytestoread = int(sys.argv[1].translate(None, 'G')) * 1024 * 1024 * 1024; while True: buffer = sys.stdin.read(bytestoread); if buffer == '': exit(); sys.stdout.write(buffer); buffer = None; # This one is for making sure the read buffer will get destroyed, otherwise we could bring our system to a halt if we have 8 GB of RAM, request a 5 GB buffer, and it ends up eating 10 GB of memory. 

要使用这个文件,像这样调用它:

 cat large.input.file | process.py | buffer.py 2G > large.output.file 

您可以使用2K来指定2千字节,2M为2兆字节,2G为2千兆字节,如果您想要为2千兆字节的缓冲区添加2T:3

使用pigz -1压缩虚拟机映像时,我总是遇到这个问题,因为这使压缩变得如此快速,磁盘开始同时读取和写入,并且磁盘的磁头开始在input并输出文件。 所以我做的是让这个小程序从标准input中读取一大块数据,将其写入标准输出,然后重复。 当读取返回一个空白string,这是因为没有收到更多的标准input,脚本结束。

它会聪明地缓冲,但没有什么好的办法来调整多less。

你可以编写一个中间程序来做你想要的caching,并从input中读取。

您的操作系统将在写入硬盘之前对文件执行各种caching,并且还会对正在读取的文件执行caching(如果可能,一般会提前阅读)。 让操作系统做缓冲和caching。

直到您可以certificate使用testing和分析硬盘驱动器是方程式中的限制因素之前,最好不要放弃它。

如果你可以改变process.py,你可以不用直接读/写pipe道来读/写,而是使用缓冲和/或memmap的文件来代替,这将有助于从系统中删除一些负载。