在C#中使用BinaryReader读取DAT文件

问题描述

我正在尝试使用BinaryReady读取DAT文件,但出现异常,不知道为什么。我收到的消息是“无法阅读流的末尾”。我的代码如下:

private void button1_Click(object sender,EventArgs e)

    {
        OpenFileDialog OpenFileDialog = new OpenFileDialog();
        OpenFileDialog.Title = "Open File...";
        OpenFileDialog.Filter = "Binary File (*.dat)|*.dat";
        OpenFileDialog.InitialDirectory = @"C:\";
        if (OpenFileDialog.ShowDialog() == DialogResult.OK)
        {
            FileStream fs = new FileStream(OpenFileDialog.FileName,FileMode.Open);
            BinaryReader br = new BinaryReader(fs);

            label1.Text = br.ReadString();
            label2.Text = br.ReadInt32().ToString();

            fs.Close();
            br.Close();
        }

我讨厌某个DAT文件,其中包含很多信息,希望能够读取它,甚至可以将其放在表格中并绘制数据。但是我使用C#已有一段时间了。因此,如果有人可以帮助我,我将不胜感激

解决方法

BinaryReader很少是读取外部文件的好选择。只有与使用BinaryWriter 写入文件的代码并行使用时,这才有意义,因为它们使用相同的约定。

想象,这里发生的事情是您对ReadString的调用试图使用对文件来说无效的约定-具体来说,它将读取一些字节(我想说4个大端字节?)作为字符串的长度前缀,然后尝试读取那么多字节作为字符串。但是,如果那不是文件内容,那就很容易了:它很容易尝试读取乱码,将其解释为巨大的数字,然后无法读取那么多字节。

如果您要处理任意文件(与BinaryWriter无关),那么您确实需要了解很多有关协议/格式的信息。鉴于文件扩展名不明确,我不会从“ .dat”中推断出任何东西-重要的是:数据是什么,它是从哪里来的?。只有有了这些信息,才能对阅读做出明智的评论。


从注释中,下面是一些(未调试的)代码,应该使您开始将内容解析为跨度:

public static YourResultType Process(string path)
{
    byte[] oversized = null;
    try
    {
        int len,offset = 0,read;
        // read the file into a leased buffer,for simplicity
        using (var stream = File.OpenRead(path))
        {
            len = checked((int)stream.Length);
            oversized = ArrayPool<byte>.Shared.Rent(len);
            while (offset < len &&
                (read = stream.Read(oversized,offset,len - offset)) > 0)
            {
                offset += read;
            }
        }
        // now process the payload from the buffered data
        return Process(new ReadOnlySpan<byte>(oversized,len));
    }
    finally
    {
        if (oversized is object)
            ArrayPool<byte>.Shared.Return(oversized);
    }
}
private static YourResultType Process(ReadOnlySpan<byte> payload)
    => throw new NotImplementedException(); // your code here