Question

Ignore/skip the first constant record which contains info like store id, location and date opened... Read the rest (info like purchase id, item name, date purchased)...

I am creating an application that decodes .bin files and displays info into a DataGridView table. When a row is selected more info is displayed into additional fields. However, unwanted data is always added in the first row of each file and sometimes the last row. I want to validate this and display only if validation's pass. My code simply adds what it sees after some conversion. When a user selects a file to import, the method Info_to_Table is called.

byte[] rec_arr = new byte[32767];
private void Info_to_Table()
{
    rec_arr = File.ReadAllBytes(import.FileName);
    FileInfo fi = new FileInfo(import.FileName);
    long length = fi.Length;
    long count = 0;

    using (FileStream Fs = new FileStream(import.FileName, FileMode.Open, FileAccess.Read))
    using (BinaryReader Br = new BinaryReader(Fs))
    {
        // Read other info here

        while ((length = Br.Read(rec_arr, (int)0, 1024)) > 0) *
        {
            // Read other info here
            Dgv.Rows.Add(DecodeLong(rec_arr, 4), count++, DecodeDateTime(rec_arr, 28));
        }

        Br.Close();
        Fs.Close();
    }
}

When a record (row) is selected:

private void Dgv_SelectionChanged(object sender, EventArgs e)
{
    To_Fields();
}

Each time a record is selected:

private void To_Fields()
{           
    rec_arr = File.ReadAllBytes(import.FileName);
    FileInfo file_info_bin = new FileInfo(import.FileName);
    long length_bin = file_info_bin.Length;
    int rec_num_to_read = Dgv.CurrentRow.Index;

    using (FileStream FS = new FileStream(import.FileName, FileMode.Open, FileAccess.Read))
    using (BinaryReader BR = new BinaryReader(FS))
    {
        do
        {
            FS.Seek(rec_num_to_read * 1024, SeekOrigin.Begin);
            // Read other info here!
            Status(rec_arr);

            foreach (var rec in rec_arr)
            {
                rec_num_to_read++;
            }
        }
        while ((length_bin = BR.Read(rec_arr, 0, 1024)) > 0);

        BR.Close();
        FS.Close();
    }
}

Is there a way of validating the file information before it populates the table? Ignoring any isn't correct? It's the entire row that is wrong if the first column's number is larger than 22500.

What it does now, this is wrong:

enter image description here

What I would like it to do, this is correct:

enter image description here

Each record in the file is 1024 characters long. I thought the solution would be in the line with * as here I am reading bytes from the stream with index as the starting point in the array. byte[], index, count.

Generally, the files look like this and all have the same structure: (large file with 682 records)

enter image description here

Was it helpful?

Solution

Since you didn't provide any description of the data you're dealing with, it's hard to come up with anything better than this:

while ((length = Br.Read(rec_arr, (int)0, 1024)) > 0) *
{
    // Read other info here
    var foo = DecodeLong(rec_arr, 4);

    if (foo != 825045041)
        Dgv.Rows.Add(foo, count++, DecodeDateTime(rec_arr, 28));
}

And in the To_Fields method you can just skip one record:

int rec_num_to_read = Dgv.CurrentRow.Index + 1;

However, I tried to run your code with the data from the screenshot, and it didn't work. I skip 1024 bytes (the unwanted record) and what I get from the beginning of the next record doesn't seem to be valid either. The value is 542966816, and the date is just mess. I don't know the date format, but it's clear that there's something wrong.

I don't have enough reputation to post images, so here's a link: http://i.stack.imgur.com/AdIAa.gif


I'd like to add that several statements are useless.

You don't need to call Close(), that's what using is for. Explanation on MSDN.

Br.Close();
Fs.Close();

The other remarks are true, if there's no code you have omitted.

Reading is done in a loop, so ReadAllBytes is not needed.

rec_arr = File.ReadAllBytes(import.FileName);

length is not used either.

FileInfo fi = new FileInfo(import.FileName);
long length = fi.Length;

And one more thing, long is 64 bit in C#. Use int which is 32 bit instead. So it's better to rename DecodeLong to DecodeInt32, because it's quite confusing really.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top