12

我有许多要导入数据库的大型 csv 文件(每个 1-10 gb)。对于每个文件,我需要替换第一行,以便将标题格式化为列名。我目前的解决方案是:

using (var reader = new StreamReader(file))
{
    using (var writer = new StreamWriter(fixed))
    {
        var line = reader.ReadLine();
        var fixedLine = parseHeaders(line);
        writer.WriteLine(fixedLine);

        while ((line = reader.ReadLine()) != null)
            writer.WriteLine(line);
    }
}

什么是只替换第 1 行而不遍历这些大文件的每一行的更快方法?

4

2 回答 2

7

如果您可以保证它fixedLine的长度与 相同(或更少)line,则可以就地更新文件而不是复制它们。

如果没有,您可能会通过访问.BaseStream您的StreamReaderandStreamWriter并执行大块复制(例如,使用 32K 字节缓冲区)来进行复制,从而获得一点性能改进,这至少可以消除检查每个字符以查看的时间如果它是一个行尾字符,就像现在发生的那样reader.ReadLine()

于 2012-12-06T16:49:14.063 回答
6

唯一可以显着加快速度的是您是否真的可以替换第一行。如果新的第一行不长于旧的 - 请仔细替换(如果需要,使用空格填充)第一行。

否则 - 您必须创建新文件并在第一行之后复制其余文件。您可以通过将缓冲区大小/显式复制调整为二进制/每个分配大小来优化复制,但这不会改变您需要复制整个文件的事实。

如果您打算将 CSV 数据放入 DB 中,还有一个技巧:如果顺序无关紧要,您可以从头开始读取一些行,将它们替换为新标题并将删除的行添加到文件末尾。

旁注:如果这是一次性操作,我只需复制文件并完成它......调试将数据插入到具有可能不同编码的文本文件中间的代码可能不值得努力。

于 2012-12-06T16:48:23.367 回答