验证可从.BIN文件添加到DataGridView的潜在新行

时间:2014-04-09 07:49:40

标签: c# winforms visual-studio datagridview .net-3.5

忽略/跳过包含商店ID,位置和日期等信息的第一个常量记录...阅读其余信息(购买ID,商品名称,购买日期等信息)......

我正在创建一个解码.bin文件并将信息显示到DataGridView表的应用程序。选择行时,会在其他字段中显示更多信息。但是,不需要的数据总是添加到每个文件的第一行,有时是最后一行。我想验证这一点并仅在验证通过时显示。我的代码只是添加了一些转换后看到的内容。当用户选择要导入的文件时,将调用方法Info_to_Table。

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

选择记录(行)时:

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

每次选择记录时:

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

有没有办法在填充表格之前验证文件信息?忽略任何不正确?如果第一列的数字大于22500,则整行都是错误的。

现在做什么,这是错误

enter image description here

我希望它能做什么,这是正确

enter image description here

文件中的每条记录长度为1024个字符。我认为解决方案将与*一致,因为我正在从流中读取字节,索引作为数组的起始点。 byte [],index,count

通常,文件看起来像这样,并且都具有相同的结构:(具有682条记录的大文件)

enter image description here

1 个答案:

答案 0 :(得分:0)

由于您没有提供您正在处理的数据的任何描述,因此很难找到比这更好的数据:

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

To_Fields方法中,您可以跳过一条记录:

int rec_num_to_read = Dgv.CurrentRow.Index + 1;

但是,我尝试使用屏幕截图中的数据运行您的代码,但它无效。我跳过1024字节(不需要的记录),我从下一条记录的开头得到的东西似乎也没有效果。值为542966816,日期只是一团糟。我不知道日期格式,但很明显有错误。

我没有足够的声誉来发布图片,所以这里有一个链接:http://i.stack.imgur.com/AdIAa.gif


我想补充几句话是没用的。

您无需致电Close(),这就是using的用途。 Explanation on MSDN

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

如果没有您省略的代码,其他评论都是正确的。

阅读是在循环中完成的,因此不需要ReadAllBytes

rec_arr = File.ReadAllBytes(import.FileName);

length也未被使用。

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

还有一件事,long在C#中是64位。使用32位代替int。因此,最好将DecodeLong重命名为DecodeInt32,因为它真的很混乱。