C# 如何打开二进制文件并将其存储在 16 位缓冲区中

本文关键字:缓冲区 存储 何打开 二进制文件 | 更新日期: 2023-09-27 18:37:18

我正在编写一个程序来进行一些图像处理。 我正在使用原始二进制文件,我需要将原始文件中的数据写入 16 位缓冲区。 我几乎得到了它,但我不太确定如何进行转换。 这是我到目前为止的代码:

        Int16[] pixelBuffer;
        String inFile;
        String outFile;        
        /// Constructor. Allocates space for 3032x2016 16-bit values.
        /// <param name="inputFile">Name of the binary input file to be read.</param>
        /// <param name="outputFile">Name of the binary output file to be written.</param>
        public ColorCorrector(String inputFile, String outputFile)
        {
        this.inFile = inputFile;
        this.outFile = outputFile;
        this.pixelBuffer = new Int16[6112512];
        //I need to open the binary file 'inputFile' and store 16-bit values in pixelBuffer.
    }

任何帮助将不胜感激!

C# 如何打开二进制文件并将其存储在 16 位缓冲区中

using (var inputStream = File.Open(inputFile))      
using (var reader = new BinaryReader(inputStream))      
{           
    int index = 0;
    while (inputStream.Position < inputStream.Length)
        pixelBuffer[index++] = reader.ReadInt16();      
}

如果你想要最好的性能,我建议你使用 FileStream 类读入一个固定大小byte[]缓冲区(大约 64KB)。

您可以使用不安全的代码将每个缓冲区复制到Int16[]中。只需几行即可完成复制,而且速度很快,因为不需要轮班和转换等。这只是一个紧密的复制循环。

我估计BinaryReader慢了10倍左右。现代CPU喜欢没有分支的紧密循环,而BinaryReader无法提供这一点。

如果需要全部在内存中,不妨使用原始byte[]缓冲区。你可以假装这实际上是通过unsafe short/ushort

 byte[] raw = File.ReadAllBytes(inputPath);
 unsafe
 {
     fixed(byte* ptr = raw)
     {
         ushort* pixels = (ushort*)ptr;
         pixels[0] = 0; // <=== your changes, etc
     }
 }
 File.WriteAllBytes(outputPath, raw);

注意:您可能需要检查文件的字节序是什么。我在上面做了ushort,因为ushort对 MSB 设置的值使用"shift"操作的人来说,这不会带来更少的意外。如果它实际上并不代表一个数字(而只是:数据),通常更容易将其视为无符号。

你应该看看System.IO.BinaryReader以及System.Drawing.Bitmap,这些可能是你正在寻找的。

您可以从FileStream进行BinaryReader,并使用 ReadInt16() 方法从流中读取 16 位整数。