【问题标题】:Binary file read pre-defined number of Byte/ Bytes using C#二进制文件使用 C# 读取预定义的字节数/字节数
【发布时间】:2014-05-08 00:41:37
【问题描述】:

场景 我有一个二进制文件,它是某个系统的输出。供应商已经向我们提供了文件编码的描述。它非常复杂,因为编码遵循某种方法。例如。第一个字节是 ISO 编码的,我们需要先对其进行解码,如果值与提供的列表匹配,则它具有一定的意义。然后接下来的 15 Bytes 也是 ISO 编码的,我们需要对其进行解码和比较。类似地,在某个位置之后,很少有字节被二进制编码..等等。

目前的行动 我将使用 C# WinForm 应用程序。到目前为止,我查看了各种文档,并且都指向 FileStream/BinaryReader 组合,因为我的文件大小在 1G 到 1.8G 的范围内。我也不能将整个文件放在 Byte[] 中。

问题 我在逐字节读取文件时遇到问题。根据上述情况,首先我只需要读取 1 个字节,然后是 15 个字节,然后是 10 个字节,依此类推。如何做到这一点。提前感谢您的帮助。

【问题讨论】:

  • Stream 和 BinaryReader 都有读取单个字节和读取多个字节的方法(Stream: ReadByte/Read, BinaryReader: ReadByte/ReadBytes)——它们都不需要你将整个文件读入一个字节[]。

标签: c# character-encoding binaryfiles


【解决方案1】:

BinaryReader 是要走的路,因为它使用流,内存使用率会很低。

现在您可以执行以下操作:

internal struct MyHeader
{
    public byte FirstByte;
    // etc
}

internal class MyFormat
{
    private readonly string _fileName;

    private MyFormat(string fileName)
    {
        _fileName = fileName;
    }


    public MyHeader Header { get; private set; }

    public string FileName
    {
        get { return _fileName; }
    }


    public static MyFormat FromFileName(string fileName)
    {
        if (fileName == null) throw new ArgumentNullException("fileName");

        // read the header of your file
        var header = new MyHeader();
        using (var reader = new BinaryReader(File.OpenRead(fileName)))
        {
            byte b1 = reader.ReadByte();
            if (b1 != 0xAA)
            {
                // return null or throw an exception
            }
            header.FirstByte = b1;

            // you can also read block of bytes with a BinaryReader
            var readBytes = reader.ReadBytes(10);

            // etc ... whenever something's wrong return null or throw an exception
        }

        // when you're done reading your header create and return the object
        var myFormat = new MyFormat(fileName);
        myFormat.Header = header;

        // the rest of the object is delivered only when needed, see method below

        return myFormat;
    }

    public object GetBigContent()
    {
        var content = new object();
        // use FileName and Header property to get your big content and return it
        // again, use a BinaryReader with 'using' statement here
        return content;
    }
}

说明

调用MyFormat.FromFileName 在其中创建这些对象之一:

  • 你解析头部,每当发生错误时返回 null 或抛出异常
  • 一旦您的标头被解析,您就可以创建对象并返回它就是这样

由于您只是阅读标题,请提供一种方法来阅读文件中较大的部分。

伪例子:

当您需要阅读大部分内容时,请使用GetBigContent 或任何您想调用的名称。

在该方法中使用HeaderFileName,您将拥有从该文件中返回内容所需的一切按需

通过使用这种方法,

  • 您只需解析其标头即可快速返回一个有效对象
  • 您在第一次通话时不会消耗 1.8Gb
  • 您只返回用户需要的内容,按需

对于与编码相关的内容,Encoding 类可能会对您有所帮助: http://msdn.microsoft.com/en-us/library/system.text.encoding.aspx

【讨论】:

    【解决方案2】:

    BinaryReader.ReadBytes 方法
    从当前流中读取指定数量的字节到一个字节数组中,并将当前位置前进该字节数。

    public virtual byte[] ReadBytes(int count)
    

    http://msdn.microsoft.com/en-us/library/system.io.binaryreader.readbytes(v=vs.110).aspx

    【讨论】:

    • OP 可能知道,他正在寻找解决问题的通用方法。
    • “我只需要读取 1 个字节,然后 15 个字节,然后 10 个字节,依此类推。如何完成此操作。”我想如果有什么我的答案太长了。
    • 而且他也不能将整个 1.8Gb 的文件放在一个数组中。
    猜你喜欢
    • 1970-01-01
    • 2013-12-06
    • 1970-01-01
    • 2020-09-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多