限制从CSV文件读取的数据大小,使其只读取整行

时间:2014-01-11 14:06:37

标签: c# csv filestream

我想用C#读取大约10GB的CSV文件。我无法一次读取一行文件,并且一次只能读取32MB的最大块。

如何限制我正在阅读的数据的大小但是还要确保我只读全行?这意味着,如果一个完整的32MB意味着只读取例如100.5行,那么我想只读取完整的100行并省略半行,即使它意味着读取少于32MB。

这是我正在考虑的骨架代码(那里的评论有更多问题):

const int MAX_BUFFER = 33554432; //32MB
        byte[] buffer = new byte[MAX_BUFFER];
        int bytesRead;
        using (System.IO.FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read))
            while ((bytesRead = fileStream.Read(buffer, 0, MAX_BUFFER)) != 0)
            {
                //should I somehow analyze here if what I'm reading containing only full lines? 
                //and if so, how can I know that I'm not currently reading something less than 32MB 
                //meaning bytesRead is less than that and that maybe I'm going to read the rest of the line in the next iteration?
            }

1 个答案:

答案 0 :(得分:2)

您无需确保阅读全线。

通过块将文件读入缓冲区。

逐个字符地处理缓冲区中的每一行,直到到达换行符。如果你在一条线上并到达缓冲区的末尾,请保留该部分,读取下一个块,并将从新读取到新行的所有内容连接到上一次读取的左侧。

如果缓冲区的最后一个字节是一个换行符,那么你就可以使用整行,只需移动下一个块即可。如果没有,请读取下一个块 - 要么第一个字节是新行,要么在它之前有其他字符。无论哪种方式,将所有内容连接到换行符(即使这意味着0个字符)并从下一个开始。

如果你在换行后点击了文件的末尾,那么你已经完成了。如果在处理非换行符时遇到文件末尾,则由您决定是将它们保留为有效行还是丢弃它们。

这与circular buffer非常相似。

另一种解决方案可能是使用BufferedStream并指定缓冲区大小。然后只需逐字节读取每个换行符或EOF。