Reading a DAT file with BinaryReader in C#

Viewed 362

Im trying to read a DAT file with BinaryReady but I get an exception and don't see why. " Unable to read beyond the end of the stream" is the message I get. My code looks like this:

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();
        }

I hat a certain DAT file with a lot of information and was hoping to be able to read it out and maybe even place it in a table and plot the data. But its been a while I worked with C#. So if anyone could help me I would highly appreciate

1 Answers

BinaryReader is very rarely a good choice for reading an external file; it only really makes sense when used in parallel with code that writes the file using BinaryWriter, since they use the same conventions.

I imagine that what is happening here is that your call to ReadString is trying to use conventions that aren't valid for your file - specifically, it will be reading some bytes (I want to say 4, big endian?) as a length prefix for the string, and then trying to read that many bytes as the string. But if that isn't what the file contents are: that could easily try to read gibberish, interpret it as a huge number, and then fail to read that-many bytes.

If you're processing an arbitrary file (nothing to do with BinaryWriter), then you really need to know a lot about the protocol/format. Given that file extensions are ambiguous, I'm not going to infer anything from ".dat" - what matters is: what is the data and where did it come from?. Only with that information can a sensible comment on reading it be made.


From the comments, here's some (untested) code that should get you started in terms of parsing the contents as a span:

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, 0, len));
    }
    finally
    {
        if (oversized is object)
            ArrayPool<byte>.Shared.Return(oversized);
    }
}
private static YourResultType Process(ReadOnlySpan<byte> payload)
    => throw new NotImplementedException(); // your code here
Related