用于读取不同数据类型的循环&从文件中删除非常大的字节数组

时间:2013-06-14 07:24:51

标签: c# .net large-files binaryreader

我有一个存储在文件(rawbytes.txt)上的原始字节流,我需要解析并输出到CSV样式的文本文件。

原始字节的输入(当读取为字符/ long / int等时)看起来像这样:

A2401028475764B241102847576511001200C...

解析它应该看起来像:

OutputA.txt

(Field1,Field2,Field3) - heading

A,240,1028475764

OutputB.txt

(Field1,Field2,Field3,Field4,Field5) - heading

B,241,1028475765,1100,1200

OutputC.txt

C,...//and so on

本质上,它是一个十六进制转储式的字节输入,它是连续的,没有任何行终止符或需要解析的数据之间的间隙。如上所示,数据一个接一个地包含不同的数据类型。

这是我的代码片段 - 因为在任何字段中都没有逗号,并且不需要使用“”(即CSV包装器),我只是使用TextWriter来创建CSV样式的文本文件,如下所示:

if (File.Exists(fileName))
        {
        using (BinaryReader reader = new BinaryReader(File.Open(fileName, FileMode.Open)))
            {

                inputCharIdentifier = reader.ReadChar();
                switch (inputCharIdentifier)
                     case 'A':

                        field1 = reader.ReadUInt64();
                        field2 = reader.ReadUInt64();
                        field3 = reader.ReadChars(10);
                        string strtmp = new string(field3);
                        //and so on
                        using (TextWriter writer = File.AppendText("outputA.txt"))
                        {
                            writer.WriteLine(field1 + "," + field2 + "," + strtmp); // +  
                        }
                        case 'B':
                        //code...

我的问题很简单 - 如何使用循环来读取整个文件?通常,它超过1 GB(排除File.ReadAllBytes和Best way to read a large file into a byte array in C#?建议的方法) - 我考虑使用while循环,但peekchar不适用于此处。此外,情况A,B等具有不同大小的输入 - 换句话说,A可能总共40个字节,而B是50个字节。因此,使用固定大小的缓冲区,例如inputBuf [1000]或[50] - 如果它们的大小相同 - 也不会很好,AFAIK。

有什么建议吗?我对C#相对较新(2个月),所以请保持温和。

1 个答案:

答案 0 :(得分:0)

您可以逐字节读取文件,并将其附加到currentBlock字节数组,直到找到下一个块。如果字节标识了新块,则可以使用currentBlock技巧解析case并创建currentBlock = characterJustRead。

即使下一个块的id超过1个字节,这种方法仍然有效 - 在这种情况下,你只需要解析currentBlock[0,currentBlock.Lenght-lenOfCurrentIdInBytes] - 换句话说你读得太多了,但是你只解析了需要的东西并使用剩下的作为下一个currentBlock的基础。

如果你想要更高的速度,你可以用X字节的块读取文件,但应用相同的逻辑。

你说“问题是数据不是100%犹太人 - 即有些情况我需要单独处理我期望识别每个块的角色不在正确位置的可能性。 “但是构建currentBlock仍然可行。代码肯定会有一些复杂的问题,可能像nextBlock,但我猜这里不知道你必须处理什么不正确的数据。