c# - 从 Process.StandardOutput 捕获二进制输出

标签 c# process binary

在 C# 中(.NET 4.0 在 SuSE 上的 Mono 2.8 下运行)我想运行一个外部批处理命令并以二进制形式捕获它的输出。我使用的外部工具称为“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 以文本格式返回记录,然后解析这些记录,但这非常慢,我希望通过直接使用二进制格式来加快速度。

最佳答案

使用 StandardOutput.BaseStream 是正确的方法,但您不得使用 cmdProcess.StandardOutput 的任何其他属性或方法。例如,访问 cmdProcess.StandardOutput.EndOfStream 将导致 StandardOutputStreamReader 读取部分流,删除您要访问的数据.

相反,只需从 br 中读取和解析数据(假设您知道如何解析数据,并且不会读取超过流的末尾,或者愿意捕获 EndOfStreamException)。或者,如果您不知道数据有多大,请使用 Stream.CopyTo将整个标准输出流复制到新文件或内存流。

关于c# - 从 Process.StandardOutput 捕获二进制输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4143281/

相关文章:

javascript - 与 SPA 应用程序和 API 的 session

c# - 从动态类型创建泛型类的实例

c - exevp 跳过所有代码,直到 c 中的 wait 调用

node.js - Nodejs 读取某些进程的标准输出并执行操作

c# - 你如何在 C# 中将字符串转换为 ascii 和二进制?

file - 使用二进制读写将实数数据读入 Fortran 中的复数变量

c# - C#中个别程序集无法卸载是什么原因

c# - 如何查询 Entity Framework 中的非映射属性?

c# - 如何获取更新剪贴板的应用程序的进程ID或名称?

php - 在 Linux 上的二进制文件中提取到 x00 的特定偏移量之后的字符串