使用subprocess.Popen进行非常大的输入和管道输入

sea*_*avi 11 python subprocess popen

我有一个非常简单的问题.我有一个大文件,经过三个步骤,使用外部程序的解码步骤,python中的一些处理,然后使用另一个外部程序重新编码.我一直在使用subprocess.Popen()来尝试在python中执行此操作,而不是形成unix管道.但是,所有数据都缓冲到内存中.是否存在执行此任务的pythonic方法,或者我最好回退到一个简单的python脚本,该脚本从stdin读取并使用unix管道写入stdout?

import os, sys, subprocess

def main(infile,reflist):
    print infile,reflist
    samtoolsin = subprocess.Popen(["samtools","view",infile],
                                  stdout=subprocess.PIPE,bufsize=1)
    samtoolsout = subprocess.Popen(["samtools","import",reflist,"-",
                                    infile+".tmp"],stdin=subprocess.PIPE,bufsize=1)
    for line in samtoolsin.stdout.read():
        if(line.startswith("@")):
            samtoolsout.stdin.write(line)
        else:
            linesplit = line.split("\t")
            if(linesplit[10]=="*"):
                linesplit[9]="*"
            samtoolsout.stdin.write("\t".join(linesplit))
Run Code Online (Sandbox Code Playgroud)

use*_*379 8

Popen有一个bufsize参数,它将限制内存中缓冲区的大小.如果您根本不想要内存中的文件,则可以将文件对象作为stdinstdout参数传递.从子流程文档:

bufsize,如果给定,具有与内置open()函数的相应参数相同的含义:0表示无缓冲,1表示行缓冲,任何其他正值表示使用(大约)该大小的缓冲区.负bufsize意味着使用系统默认值,这通常意味着完全缓冲.bufsize的默认值为0(无缓冲).

  • 来自文档:版本 3.3.1 中的更改:bufsize 现在默认为 -1,以默认启用缓冲以匹配大多数代码期望的行为。 (2认同)

ani*_*haw 5

尝试做出这个小改动,看看效率是否更好.

 for line in samtoolsin.stdout:
        if(line.startswith("@")):
            samtoolsout.stdin.write(line)
        else:
            linesplit = line.split("\t")
            if(linesplit[10]=="*"):
                linesplit[9]="*"
            samtoolsout.stdin.write("\t".join(linesplit))
Run Code Online (Sandbox Code Playgroud)