【问题标题】:Best way to write huge string into a file将大字符串写入文件的最佳方法
【发布时间】:2011-06-28 23:31:28
【问题描述】:

在 C# 中,我正在读取中等大小的文件(100 KB ~ 1 MB),修改部分内容,最后写入不同的文件。所有内容均为文字。修改是作为字符串对象和字符串操作完成的。我目前的做法是:

  1. 使用StreamReader从原始文件中读取每一行。
  2. 打开StringBuilder 以获取新文件的内容。
  3. 修改字符串对象,调用StringBuilderAppendLine(直到文件结束)
  4. 打开一个新的StreamWriter,并将StringBuilder 写入写入流。

但是,我发现 StremWriter.Write 会截断 32768 个字节 (2^16),但 StringBuilder 的长度大于此。我可以编写一个简单的循环来保证整个字符串到一个文件中。但是,我想知道在 C# 中执行此任务最有效的方法是什么?

总而言之,我只想修改文本文件的某些部分并写入不同的文件。但是,文本文件的大小可能大于 32768 字节。

== 回答 == 很抱歉让你迷惑了!只是我没有打电话给flushStremWriter.Write 没有短的(例如 2^16)限制。

【问题讨论】:

  • 我认为使用字符串生成器是更好的方法
  • 你是刷新还是关闭你的 StreamWriter?
  • Flush 将在您关闭编写器时自动调用(您确实应该这样做)。要关闭编写器,您应该调用 Dispose 而不是 Close,以便释放非托管资源。最好的方法是使用 using 语句。
  • 那么...修复仍然是调用 Flush,还是有其他工作?有sn-p吗?我在 HttpModule 中遇到了同样的问题。
  • 没关系...我刚试过。成功了!

标签: c# string file stream


【解决方案1】:

你可以试试这个吗:

    void Test()
    {
        using (var inputFile = File.OpenText(@"c:\in.txt"))
        {
            using (var outputFile = File.CreateText(@"c:\out.txt"))
            {
                string current;
                while ((current = inputFile.ReadLine()) != null)
                {
                    outputFile.WriteLine(Process(current));
                }
            }
        }
    }

    string Process(string current)
    {
        return current.ToLower();
    }

通过逐行处理并直接写入,避免了必须将文件加载到内存中

【讨论】:

    【解决方案2】:

    我不会通过漏洞文档运行,而是使用正则表达式来查找您正在寻找的样本:

    public List<string> GetAllProfiles()
        {
            List<string> profileNames = new List<string>();
            using (StreamReader reader = new StreamReader(_folderLocation + "profiles.pg"))
            {
                string profiles = reader.ReadToEnd();
                var regex = new Regex("\nname=([^\r]{0,})", RegexOptions.IgnoreCase);
                var regexMatchs = regex.Matches(profiles);
                profileNames.AddRange(from Match regexMatch in regexMatchs select regexMatch.Groups[1].Value);
            }
            return profileNames;
        }
    

    【讨论】:

      【解决方案3】:

      嗯,这完全取决于您要修改的内容。如果您对文本文件一部分的修改依赖于文本文件的另一部分,那么您显然需要将这两个部分都保存在内存中。但是,如果您只需要逐行修改文本文件,请使用以下内容:

      using (StreamReader sr = new StreamReader(@"test.txt"))
      {
          using (StreamWriter sw = new StreamWriter(@"modifiedtest.txt"))
          {
              while (!sr.EndOfStream)
              {
                  string line = sr.ReadLine();
                  //do some modifications
                  sw.WriteLine(line);
                  sw.Flush(); //force line to be written to disk
              }
          }
      }
      

      【讨论】:

        【解决方案4】:

        StreamWriter.Write

        没有

        截断字符串,没有限制。

        在内部它使用String.CopyTo,而另一方面使用不安全代码(使用fixed)来复制字符,因此它是最有效的

        【讨论】:

          【解决方案5】:

          问题很可能与未关闭编写器有关。见http://msdn.microsoft.com/en-us/library/system.io.streamwriter.flush.aspx

          但如果可以避免,我建议不要将整个文件加载到内存中。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2016-10-19
            • 2016-08-29
            • 1970-01-01
            • 2011-04-10
            • 2020-09-01
            • 1970-01-01
            • 1970-01-01
            • 2021-09-08
            相关资源
            最近更新 更多