背景:
Linux 上的 Python 2.6.6。 DNA 序列分析流程的第一部分。
我想从已安装的远程存储(LAN)读取可能经过 gzip 压缩的文件,以及它是否经过 gzip 压缩; gunzip 将其压缩到流中(即使用gunzip FILENAME -c
),如果流(文件)的第一个字符是“@”,则将该整个流路由到一个在标准输入上获取输入的过滤程序,否则只需将其直接通过管道传输到本地磁盘上的文件。我想最大限度地减少从远程存储读取/查找文件的数量(仅一次通过文件应该不是不可能的?)。
示例输入文件的内容,前四行对应于 FASTQ 格式的一条记录:
@I328_1_FC30MD2AAXX:8:1:1719:1113/1
GTTATTATTATAATTTTTTACCGCATTTATCATTTCTTCTTTATTTTCATATTGATAATAAATATATGCAATTCG
+I328_1_FC30MD2AAXX:8:1:1719:1113/1
hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhahhhhhhfShhhYhhQhh]hhhhffhU\UhYWc
不应通过管道传输到过滤程序的文件包含如下所示的记录(前两行对应于 FASTA 格式的一条记录):
>I328_1_FC30MD2AAXX:8:1:1719:1113/1
GTTATTATTATAATTTTTTACCGCATTTATCATTTCTTCTTTATTTTCATATTGATAATAAATATATGCAATTCG
有些人编写了半伪代码来可视化我想要做的事情(我知道按照我编写的方式这是不可能的)。我希望这有一定道理:
if gzipped:
gunzip = Popen(["gunzip", "-c", "remotestorage/file.gz"], stdout=PIPE)
if gunzip.stdout.peek(1) == "@": # This isn't possible
fastq = True
else:
fastq = False
if fastq:
filter = Popen(["filter", "localstorage/outputfile.fastq"], stdin=gunzip.stdout).communicate()
else:
# Send the gunzipped stream to another file
忽略这样一个事实:代码不会像我在这里编写的那样运行,并且我没有错误处理等,所有这些都已经在我的其他代码中了。我只是想要帮助查看流或找到解决方法。如果你能的话我会很棒gunzip.stdout.peek(1)
但我意识到这是不可能的。
到目前为止我尝试过的:
我认为 subprocess.Popen 可能会帮助我实现这一目标,并且我尝试了很多不同的想法,其中包括尝试使用某种 io.BufferedRandom() 对象来写入流,但我不知道如何做到这一点会工作。我知道流是不可搜索的,但也许解决方法可能是读取gunzip流的第一个字符,然后创建一个新流,在其中首先根据文件内容输入“@”或“>”,然后填充其余部分将gunzip.stdout-stream添加到新流中。然后,这个新流将被输入到过滤器的 Popen 标准输入中。
请注意,文件大小可能比可用内存大几倍。我不想从远程存储中执行多次源文件读取,也不想进行不必要的文件访问。
欢迎任何想法!请向我提问,如果我说得不够清楚,我可以澄清。