<p>如果未缓冲地打开文件,则可以:</p>
<pre><code>import subprocess
with open('in.txt', 'rb', 0) as a, open('out.txt', 'w') as b:
header = a.readline()
rc = subprocess.call(['sort'], stdin=a, stdout=b)
</code></pre>
<p><code>subprocess</code>模块在文件描述符级别(操作系统的低级别无缓冲I/O)工作。它可以与<code>os.pipe()</code>、<code>socket.socket()</code>、<code>pty.openpty()</code>一起工作,如果操作系统支持的话,它可以使用任何有效的<code>.fileno()</code>方法。</p>
<p><em>不建议在同一文件上混合缓冲和非缓冲I/O。</em></p>
<p>在Python 2上,<code>file.flush()</code>会导致输出出现,例如:</p>
<pre><code>import subprocess
# 2nd
with open(__file__) as file:
header = file.readline()
file.seek(file.tell()) # synchronize (for io.open and Python 3)
file.flush() # synchronize (for C stdio-based file on Python 2)
rc = subprocess.call(['cat'], stdin=file)
</code></pre>
<p>没有<code>subprocess</code>模块和<code>os.read()</code>可以复制此问题:</p>
<pre><code>#!/usr/bin/env python
# 2nd
import os
with open(__file__) as file: #XXX fully buffered text file EATS INPUT
file.readline() # ignore header line
os.write(1, os.read(file.fileno(), 1<<20))
</code></pre>
<p>如果缓冲区大小很小,则打印文件的其余部分:</p>
<pre><code>#!/usr/bin/env python
# 2nd
import os
bufsize = 2 #XXX MAY EAT INPUT
with open(__file__, 'rb', bufsize) as file:
file.readline() # ignore header line
os.write(2, os.read(file.fileno(), 1<<20))
</code></pre>
<p>如果第一行的大小不能被<code>bufsize</code>整除,它将消耗更多的输入。</p>
<p>默认的<code>bufsize</code>和<code>bufsize=1</code>(行缓冲)在我的机器上的行为类似:文件的开头消失了——大约4KB。</p>
<p><code>file.tell()</code>为所有缓冲区大小报告第2行开头的位置。使用<code>next(file)</code>而不是<code>file.readline()</code>会导致<code>file.tell()</code>在Python 2上,由于<a href="http://bugs.python.org/issue3907" rel="noreferrer">read-ahead buffer bug</a>(<code>io.open()</code>给出了预期的第二行位置),所以在我的机器上大约有5公里。</p>
<p>在调用子进程之前尝试<code>file.seek(file.tell())</code>对于使用默认的基于stdio的文件对象的Python 2没有帮助。它与Python 2上的<code>io</code>、<code>_pyio</code>模块中的<code>open()</code>函数以及Python 3上的默认<code>open</code>(也基于<code>io</code>)一起工作。</p>
<p>在Python 2和Python 3上尝试<code>io</code>、<code>_pyio</code>模块时,无论是否使用<code>file.flush()</code>,都会产生各种结果。它证实了在同一个文件描述符上混合缓冲和非缓冲I/O不是一个好主意。</p>