在 C#(在 SuSE 上的 Mono 2.8 下运行的 .NET 4.0)中,我想运行外部批处理命令并以二进制形式捕获其输出。我使用的外部工具称为“samtools”(samtools.sourceforge.net),它可以从称为 BAM 的索引二进制文件格式返回记录。
我使用 Process.Start 运行外部命令,并且我知道我可以通过重定向 Process.StandardOutput 来捕获其输出。问题是,这是一个带有编码的文本流,因此它不允许我访问输出的原始字节。我发现的几乎有效的解决方案是访问底层流。
这是我的代码:
Process cmdProcess = new Process();
ProcessStartInfo cmdStartInfo = new ProcessStartInfo();
cmdStartInfo.FileName = "samtools";
cmdStartInfo.RedirectStandardError = true;
cmdStartInfo.RedirectStandardOutput = true;
cmdStartInfo.RedirectStandardInput = false;
cmdStartInfo.UseShellExecute = false;
cmdStartInfo.CreateNoWindow = true;
cmdStartInfo.Arguments = "view -u " + BamFileName + " " + chromosome + ":" + start + "-" + end;
cmdProcess.EnableRaisingEvents = true;
cmdProcess.StartInfo = cmdStartInfo;
cmdProcess.Start();
// Prepare to read each alignment (binary)
var br = new BinaryReader(cmdProcess.StandardOutput.BaseStream);
while (!cmdProcess.StandardOutput.EndOfStream)
{
// Consume the initial, undocumented BAM data
br.ReadBytes(23);
// ...更多解析如下
但是当我运行这个程序时,我读取的前 23 个字节不是输出中的前 23 个字节,而是下游数百或数千个字节。我假设 StreamReader 做了一些缓冲,因此底层流已经提前到输出(例如 4K)。底层流不支持回溯到开头。
我被困在这里了。有谁有一个工作解决方案来运行外部命令并以二进制形式捕获其标准输出?输出可能非常大,所以我想对其进行流式传输。
任何帮助表示赞赏。
顺便说一句,我当前的解决方法是让 samtools 以文本格式返回记录,然后解析这些记录,但这非常慢,我希望通过直接使用二进制格式来加快速度。
Using StandardOutput.BaseStream
是正确的方法,但您不得使用任何其他属性或方法cmdProcess.StandardOutput
。例如,访问cmdProcess.StandardOutput.EndOfStream
会导致StreamReader
for StandardOutput
读取部分流,删除要访问的数据。
相反,只需读取并解析来自的数据br
(假设您知道如何解析数据,并且不会读取超过流末尾的内容,或者愿意捕获EndOfStreamException
)。或者,如果您不知道数据有多大,请使用Stream.CopyTo http://msdn.microsoft.com/en-us/library/system.io.stream.copyto.aspx将整个标准输出流复制到新文件或内存流。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)