【问题标题】:how to increase performance for reading and writing large text file?如何提高读写大文本文件的性能?
【发布时间】:2012-08-09 08:49:20
【问题描述】:

我编写了一个程序来清理我几个月来收集的一些财务数据。它总共大约 100GB,并且每天都在增长,每个文件大约 1-2GB。它当前以文本文件格式存储。

以下代码用于清理数据:

    static void Main()
    {
        string inputString;
        string outputString;

             // others variable omitted

        string[] lineSplit;

        foreach (string fullPath in Directory.GetFiles(inputDirectory))
        {

            using (StreamReader reader = new StreamReader(fullPath))        //read from input file
            {
                while ((line = reader.ReadLine()) != null)
                {
                          //logic to clean data

                                ...

                         ///////////////////////////////////////////////////////////

                    using (StreamWriter writer = File.AppendText(outputFile))
                    {
                        writer.WriteLine(outputString);
                    }
                }
            }
        }       
    }

它非常慢,我估计 100GB 的数据大约需要 3-4 天才能完成。我知道这是关于我的 IO 操作,因为我没有缓冲区等来做。我对 C# 还是比较陌生,我找不到任何相关示例来为 IO 构建适当的缓冲区。我发现的大多数示例都是用于下载的,不适用于阅读文本文件。而且我无法将整个文件加载到内存中进行处理,因为它太大了。我该怎么做?谁能给我一些我可以使用的sn-p代码?谢谢

【问题讨论】:

    标签: c# performance io


    【解决方案1】:

    您正在每一行重新打开输出文件。将循环移动到 inside 以调用 File.AppendText 开始的块:

    using (TextReader reader = File.OpenText(fullPath))
    {
        using (TextWriter writer = File.AppendText(outputFile))
        {
             while ((line = reader.ReadLine()) != null)
             {
                 // Logic to clean data
                writer.WriteLine(outputString);
             }
        }
    }
    

    当然,这假设每个输入文件都有一个输出文件。如果不是这种情况 - 如果每一行可以转到一个小集合中的不同文件 - 您可能希望保持所有输出文件打开,并只保留一个字典(或类似的东西),以便您可以快速写入任何您想要的.

    【讨论】:

    • 随机 - Jon - 我们 (SE) 破坏了你的追踪器吗?你的配额用完了吗?
    • @MarcGravell:是的。奇怪的是它确实昨天在 Meta 上为我显示了 10 分,但 SO 是空白的。我打算明天去看看。
    • 如果您的结果没有明显问题,请告诉我们您正在调用哪些方法 - 我相信我们可以说服 Monty 查看它;p
    • 特别是,它正在返回数据:api.stackexchange.com/2.0/users/22656/…
    • @ClaytonLeung:正如我在回答中所说的那样,您可能想要一个打开文件字典之类的东西。您需要添加一个 try/finally 块,以便在最后关闭它们。
    猜你喜欢
    • 2012-01-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-02
    • 1970-01-01
    • 1970-01-01
    • 2020-09-03
    相关资源
    最近更新 更多