从 Process.StandardOutput 捕获二进制输出

2024-03-28

在 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(使用前将#替换为@)

从 Process.StandardOutput 捕获二进制输出 的相关文章

随机推荐

  • 测试 RESTful 服务的方法? [关闭]

    Closed 这个问题是无关 help closed questions 目前不接受答案 我想直接通过 HTTP 测试我的 RESTful 应用程序 并且我正在寻找可以帮助我完成该任务的工具 基本上我正在寻找一个简单的 HTTP 请求包装器
  • 我是否需要告诉 Apache Tomcat 保持 Websocket 连接打开?

    我正在尝试Apache Tomcat Websocket 实现 http tomcat apache org tomcat 7 0 doc web socket howto html 问题是 连接总是在最多 30 秒的空闲时间后关闭 我是否
  • 通过 DataMapper 来自 SQLite 内存数据库的 No Such Table 错误

    我有一个 Ruby 程序 它使用 DataMapper 作为 ORM 与内存中的 SQLite DB 进行通信 这一直工作得很好 但是我最近刚刚添加了一个新的 DM 类和相应的表 令我惊讶的是 现在在 auto migrate 过程中事情发
  • 内存保护的最新技术水平如何?

    我对 C 语言 指针和内存管理等低级语言了解得越多 我就越想了解现代操作系统和内存保护的最新技术水平 例如 采取了哪些检查来防止某些恶意程序随机尝试读取尽可能多的地址空间并忽略操作系统设置的规则 一般来说 这些内存保护方案是如何工作的 他们
  • C# Microsoft Graph - 如何从 msal-browser 发送带有访问令牌的电子邮件

    我正在使用 C Microsoft Graph 发送电子邮件 但当我调用等待 graphClient Me SendMail message Request PostAsync 时 我遇到错误 对象引用未设置到对象的实例 方法 我尝试首先调
  • 如何找到ZedGraph上的索引位置

    有没有办法根据当前的 xPosition 找到曲线的索引位置 假设我有一个曲线项目 MyCurve 它有 20k 点 当鼠标移动时我可以获得鼠标位置 然后只需使用以下函数即可获得 x 和 y 位置 double xPos 0 yPos 0
  • 错误 lnk2005 已在 .obj 中定义

    关于这个错误有很多疑问 但它们只与一个变量相关 test h namespace World enum Objects TERRAIN 1 BOX 2 SPHERE 4 CAPSULE 8 void WorldObjects2 unsign
  • 如何将 SQL 结果集限制为不太常见的项目

    问题 我有一份姓名和地址列表 有些姓名 人 与其他姓名 人 具有相同的地址 街道 邮政编码 城镇 我想选择所有这些名称 其地址出现次数不超过三次 并从其余名称中选择前三个名称 每个名称都指向同一地址 例子 Albert Adr1 Berta
  • 连续单子转变

    在尝试为 ContT monad 转换器建立一些直觉时 我 也许并不奇怪 发现自己很困惑 问题在于 shiftT 操作似乎没有做任何有用的事情 首先是一个如何使用它的简单示例 shiftT famr gt lift do a lt calc
  • 按月分组获取数据集的百分位数

    我有一个 SQL 表 其中包含大量记录 如下所示 Date Score 01 01 2010 4 02 01 2010 6 03 01 2010 10 16 03 2010 2 我将其绘制在图表上 因此我在图表上画了一条漂亮的线 表示随时间
  • 如何使用thymeleaf作为模板引擎和飞碟作为渲染器使用密码保护pdf报告

    PDF 已成功生成 但我想用密码保护它 Flying saucer pdf 文档对我没有帮助 我正在使用这个例子使用thymeleaf flying saucer pdf Spring Boot http www oodlestechnol
  • 使用把手引用 css 和 js 文件的正确方法是什么?

    我目前在我的项目中使用 Express 和车把 这是我第一次使用车把 我不知道如何正确引用我的 css 和 js 文件的位置 我当前的项目结构如下 test root views js some JS files css some css
  • Json.net 反序列化返回一个空对象

    我正在使用下面的代码进行序列化 var json JsonConvert SerializeObject new summary summary summary是类型的自定义对象SplunkDataModel public class Sp
  • Firebase Cloud Functions - 创建 pdf、存储到存储桶并通过邮件发送

    我正在开发一个 Firebase 函数 当新订单添加到实时数据库时会触发该函数 它做的第一件事是创建一个 pdf 并将其通过管道传输到谷歌云存储桶 在存储桶流的 on finish 事件上 下一个函数将启动 该函数应通过电子邮件将管道传输的
  • 如何将通知从网站发送到 Android 应用程序 [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我使用一些 javascript 和 php 制作了一个 html 网站 我使用 eclipse 和 java 制作了一个 andro
  • WebSocket - Safari 9 - 标头值中的 UTF-8 序列无效

    我正在创建一个在 Chrome 版本 47 0 2526 106 64 位 中工作的 WebSocket 但在 Safari 版本 9 0 2 11601 3 9 上失败 错误是Invalid UTF 8 sequence in heade
  • Java - 一次双加法/减法的最大精度损失

    是否有可能确定 即使是粗略地 处理两个数据时的最大精度损失是多少 doublejava中的值 加 减 最糟糕的情况可能是两个数字无法精确表示 然后对它们执行运算 结果得到的值也无法精确表示 最坏的情况是all精度可能会丢失 例如 如果结果大
  • 我应该在声明时还是在构造函数中实例化实例变量?

    这两种方法都有什么优点吗 示例1 class A B b new B 示例2 class A B b A b new B 没有什么区别 实例变量初始化实际上是由编译器放入构造函数中的 第一个变体更具可读性 您无法对第一个变体进行异常处理 另
  • 使用reactjs下载文件无法正常工作(使用axios)

    我正在使用以下方法实现 YouTube 视频下载器ytdl核心 https www npmjs com package ytdl core带有 Nodejs 后端和 Reactjs 前端 但是 使用 ytdl core 库 我可以使用此代码
  • 从 Process.StandardOutput 捕获二进制输出

    在 C 在 SuSE 上的 Mono 2 8 下运行的 NET 4 0 中 我想运行外部批处理命令并以二进制形式捕获其输出 我使用的外部工具称为 samtools samtools sourceforge net 它可以从称为 BAM 的索