You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用C# BinaryWriter导出Oracle Blob(PDF)异常,如何设置8位写入?

问题分析与解决方案

你的推测其实不准确:BinaryWriter写入byte数组时,本身就是按8位字节直接写入的,不存在“单字节写入单个字符”的编码问题——因为你操作的是原始字节流,而非字符串。PDF打开异常的原因大概率出在代码的读取/写入逻辑上,而非BitsPerComponent设置(这个参数是PDF文件内部的图像属性,和导出Blob的字节流无关)。

代码中的问题

  1. 重复覆盖文件:如果OracleDataReader返回多条记录,每次循环都会覆盖同一个C:\ttttt.pdf文件,最终只会保留最后一条Blob数据。
  2. 资源未正确释放:没有使用using语句自动管理FileStream和BinaryWriter,可能导致流未完全刷新就关闭,损坏文件。
  3. 冗余的Flush操作:在循环内频繁调用Flush()会降低性能,且无必要——流会在关闭时自动刷新。

修正后的代码

int bufferSize = 1024 * 1024; // 建议用1MB缓冲区,效率更高
byte[] blobBuffer = new byte[bufferSize];

using (OracleDataReader reader = comando.ExecuteReader(CommandBehavior.SequentialAccess))
{
    int fileIndex = 0;
    while (reader.Read())
    {
        // 如果有多条Blob记录,生成不同的文件名避免覆盖
        string filePath = $"C:\\ttttt_{fileIndex}.pdf";
        fileIndex++;

        // using语句自动释放流资源,无需手动Close()
        using (FileStream fs = new FileStream(filePath, FileMode.Create, FileAccess.Write))
        using (BinaryWriter writer = new BinaryWriter(fs))
        {
            long currentIndex = 0;
            long bytesReturned = reader.GetBytes(0, currentIndex, blobBuffer, 0, bufferSize);

            while (bytesReturned > 0)
            {
                writer.Write(blobBuffer, 0, (int)bytesReturned);
                currentIndex += bytesReturned;
                bytesReturned = reader.GetBytes(0, currentIndex, blobBuffer, 0, bufferSize);
            }
        }
    }
}

关键说明

  • using语句:确保FileStream、BinaryWriter和OracleDataReader在使用后自动释放资源,避免文件损坏。
  • 缓冲区大小:改用1MB级别的缓冲区比10KB更高效,减少IO操作次数。
  • 多记录处理:通过添加文件索引后缀,避免多条Blob记录覆盖同一个文件。
  • 读取逻辑优化:直接判断bytesReturned > 0,覆盖所有读取完成的情况,比原代码的== bufferSize更严谨。

如果修正后仍无法打开PDF,建议:

  • 对比原始Blob的字节大小和导出文件的大小,确认是否完全读取。
  • 用文本编辑器打开导出的PDF,查看开头是否为%PDF-(PDF文件的标准头),如果不是说明读取的Blob数据本身有问题。

内容的提问来源于stack exchange,提问作者user2232273

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 06:20:45