【问题标题】:Writing very large datasets to textfile将非常大的数据集写入文本文件
【发布时间】:2011-09-13 23:40:37
【问题描述】:

我有一个非常大的数据集,我目前正在将其写入文本文件 (IO)。它非常慢并且导致系统消耗大量资源,因为有 10 的数千行。

我想知道是否有人可以推荐一个好方法来减少我的系统负载或至少平滑过程以避免对内存资源等的需求出现大幅峰值。我不介意这是否意味着这需要更长的时间,但只要它不会给机器带来太多负载。

【问题讨论】:

  • 您是否使用缓冲 I/O?我不太了解 C#,但在 Java 中它是一种方式,但它只有在您经常重复调用 I/O 操作时才有帮助......
  • 请展示您的代码以便提出改进建议。

标签: c# io


【解决方案1】:

您的问题几乎没有意义,但假设您正在从数据库中读取结果,您可以将它们分块写入文件以避免将整个数据集加载到内存中,就像这样:

using (var conn = new SqlConnection(SomeConnectionString))
using (var cmd = conn.CreateCommand())
{
    conn.Open();
    cmd.CommandText = "SELECT foo, bar FROM baz;";
    using (var reader = cmd.ExecuteReader())
    {
        using (var writer = new StreamWriter("result.txt"))
        {
            while (reader.Read())
            {
                var foo = reader.GetString(reader.GetOrdinal("foo"));
                var bar = reader.GetInt32(reader.GetOrdinal("bar"));
                writer.WriteLine(string.Format("{0}, {1}", foo, bar));
            }
        }
    }
}

就内存消耗而言,这将是摇滚乐,而就性能而言,这当然取决于 SQL 查询的优化和 SQL 服务器的功能。

【讨论】:

    【解决方案2】:

    如果系统不依赖于此,您可以生成一个线程来进行实际写入并尝试对其进行批处理/缓冲,以最大程度地减少 CPU/内存峰值。这取决于您的具体情况,您没有提供太多信息:)

    【讨论】:

      【解决方案3】:

      StreamWriter写文件我最近不得不写一个300万行的文件,看起来效果很好。确保您还在流中读取大量数据。

      【讨论】:

        【解决方案4】:

        在这种情况下,您不应将整个数据集加载到内存中。考虑到我使用 NHibernate 作为我的 ORM,对于这种情况,我会从 DB 中小批量读取,例如每个事务一次 100 行。这样在任何给定时刻我的内存将只保存 100 行数据而不是 100000 行,将 100 行写入文件,然后再次从数据库中读取接下来的 100 行并写入文件等。

        寻找分页。

        【讨论】:

          【解决方案5】:

          写入文件的一种解决方案是使用 log4Net 写入文件。

          有效且不占用太多资源。

          【讨论】:

          • Log4Net 用于将数据库行写入文件?
          • 使用日志框架将大型数据集写入文件似乎非常违反直觉。您是否有任何证据表明这将比 System.IO.File 类更有效?
          • 我自己开发了一个使用 Log4xxx 将数据写入文本文件的高性能程序。它工作正常,不会对系统性能产生很大影响。我想你会在你的 prog 中使用 Log4Net。所以,只需为这个任务创建一个FileAppender,然后创建一个新的线程来保存写入文件任务,在制作日志消息时使用StringBuffer而不是String,然后放手。
          猜你喜欢
          • 2019-10-20
          • 1970-01-01
          • 2013-05-08
          • 2016-10-10
          • 2016-11-21
          • 2017-05-13
          • 2023-03-03
          • 1970-01-01
          • 2016-11-21
          相关资源
          最近更新 更多