【问题标题】:how to insert row in first line of text file?如何在文本文件的第一行插入行?
【发布时间】:2011-01-24 23:36:15
【问题描述】:

我有一个测试文件包含

1,2,3
2,3,4
5,6,7

我想在第一行插入这个:A,B,C

所以我得到:

A,B,C
1,2,3
2,3,4
5,6,7

我该怎么做?

【问题讨论】:

    标签: c#


    【解决方案1】:

    这里有一个链接,它解释了如何在 C# 中使用 TextReader (StreamReader) 和 TextWriter (StreamWriter) 类。

    http://www.csharpfriends.com/Articles/getArticle.aspx?articleID=132

    虽然这是特定于 C# 的,但该方法在许多语言中可能相对相同。

    (注意:有几种方法可以做到这一点,这只是一个很快想到的想法。)

    基本上,您可以将文本文件的内容读入一个字符串,找到该字符串的开头,写入您的信息(A、B、C 与您的回车或换行符),然后将该信息写回进入文本文件覆盖原始内容并保存。

    【讨论】:

    • 如果您的文件是 10MB 或 100MB 怎么办?您会将所有内容读入字符串(在内存中)吗?这不是很有效。
    • +1 - 很容易相信您可以在文件开头“插入”一行,而其余部分保持不变。那样是行不通的,所以你指出来是对的。
    • Joshua 确实提到了 StreamReader 和 StreamWriter。如果 Gold 两者都使用,那么它可以逐行完成,这同样不是很有效,但它可以工作而不用担心 OutOfMemoryException。
    • 答案是:'您可以将文本文件的内容读入字符串'。这只是一个坏主意,除非您确定文件永远不会大于某个大小(取决于您的环境)。
    【解决方案2】:

    您不能在文本文件中“插入”任何内容。

    你必须这样做

    • 复制内容
    • 在适当的时候惰性化额外数据
    • 关闭文件
    • 删除原名并将新名称重命名为旧名称

    【讨论】:

    • @rwwilden:您似乎在倡导不可能的事情。你测试过这个理论吗?查看您的答案的 cmets。
    • @rwwilden:实际上 IS 是真的,您只能“在末尾插入”即追加,其他任何内容都会覆盖现有文件的一部分。
    • 对不起,我的回答只是覆盖了文件的一部分,根本没有插入。
    【解决方案3】:

    与前面的答案类似,但这说明了如何在最小化内存消耗的同时做你想做的事情。即使您在读/写流中打开它,也无法读取您要修改的整个文件,因为您无法“插入”数据。

    static void WriteABC(string filename)
    {
        string tempfile = Path.GetTempFileName();
        using (var writer = new StreamWriter(tempfile))
        using (var reader = new StreamReader(filename))
        {
            writer.WriteLine("A,B,C");
            while (!reader.EndOfStream)
                writer.WriteLine(reader.ReadLine());
        }
        File.Copy(tempfile, filename, true);
    }
    

    【讨论】:

    • 太棒了,但我想知道,我们到底应该是“File.Delete(tempfile)”还是让系统清理更好?
    • 是的,最好把文件删掉,为什么要留下我们不再需要的东西?
    【解决方案4】:

    我认为这个答案更简单快捷:

    public static void WriteToFile(string Path, string Text)
    {
        string content = File.ReadAllText(Path);
        content = Text + "\n" + content;      
        File.WriteAllText(Path, content);
    }
    

    那么你就可以调用它了:

    WriteToFile("yourfilepath", "A,B,C");
    

    【讨论】:

    • 它适用于较小的文件,但对于较大的文件,您可能会遇到内存问题。
    • 我们需要指定编码,否则,它会很好地读取一个文件,然后用不同的编码写入它。
    【解决方案5】:

    @Jake:StringBuilder 更好更简单

    public static void WriteToFile(string path, string text)
    {
            StringBuilder stringBuilder = new StringBuilder();
    
            stringBuilder.AppendLine("a,b,c");
            stringBuilder.Append(File.ReadAllText(path)).AppendLine();
            File.WriteAllText(path, stringBuilder.ToString()); 
    }
    

    编辑: 但是StringBuilder有一个缓冲区限制:Maximum Capacity 2147483647

    【讨论】:

      【解决方案6】:

      聚会迟到了……

      好问题。您可以使用此代码:

      static void WriteABC2(string filename)
      {
          string tempfile = Path.GetTempFileName();
          using (var writer = new FileStream(tempfile, FileMode.Create))
          using (var reader = new FileStream(filename, FileMode.Open))
          {
              var stringBytes = Encoding.UTF8.GetBytes("A,B,C" + Environment.NewLine);
              writer.Write(stringBytes, 0, stringBytes.Length);
      
              reader.CopyTo(writer);
          }
          File.Copy(tempfile, filename, true);
          File.Delete(tempfile);
      }
      

      此代码基于出色的Jake 答案,但我使用FileStream 而不是StreamWriterStreamReader。在处理大文件时,使用FileStream 可以显着提高性能(甚至比我的测试快 4 倍)。为了清楚一点,我做了一些测试,并在下面报告了结果。

      我是如何进行测试的

      我创建了 7 个文件。每个文件包含 10^X 行,其名称为 file<line count>.txt。所以文件列表是:

      | File name       | Line count | File size |
      |-----------------|------------|-----------|
      | file1.txt       |          1 | 66 byte   |
      | file10.txt      |         10 | 678 byte  |
      | file100.txt     |        100 | 6,72 KB   |
      | file1000.txt    |       1000 | 68,2 KB   |
      | file10000.txt   |      10000 | 692 KB    |
      | file100000.txt  |     100000 | 6,85 MB   |
      | file1000000.txt |    1000000 | 69,5 MB   |
      

      每个文件的每一行组成如下:

      <line index starting from 0> - abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789
      

      例如file10.txt的前两行是:

      0 - abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789
      1 - abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789
      

      我使用以下代码进行测试并获取函数执行持续时间:

      var stopwatch = new Stopwatch();
      
      long abcTotalDuration = 0;
      long abc2TotalDuration = 0;
      
      string fileInput = "file1.txt";
      string outputFolder = "output";
      
      for (int i = 0; i < 100; i++)
      {
          string filename1 = Path.Combine(outputFolder, Guid.NewGuid().ToString());
          string filename2 = Path.Combine(outputFolder, Guid.NewGuid().ToString());
      
          stopwatch.Restart();
          WriteABC(fileInput, filename1);
          stopwatch.Stop();
          abcTotalDuration += stopwatch.ElapsedMilliseconds;
      
          stopwatch.Restart();
          WriteABC2(fileInput, filename2);
          stopwatch.Stop();
          abc2TotalDuration += stopwatch.ElapsedMilliseconds;
      
          File.Delete(filename1);
          File.Delete(filename2);
      }
      
      Console.WriteLine("ABC : " + abcTotalDuration.ToString());
      Console.WriteLine("ABC2: " + abc2TotalDuration.ToString());
      
      // Just to wake me up :-)
      Console.Beep(800, 1000);
      
      Console.ReadKey();
      

      测试包括为每个指定文件添加A,B,C(new line)。结果保存在单独的文件中(仅用于测试)。

      我为每个输入文件启动了 5 次代码(在 fileInput 变量中指定)。每次我启动代码时,WriteABCWriteABC2 函数都会执行 100 次。

      以下是结果(均以毫秒为单位):

      处理file1.txt

            | ABC | ABC2 |
            |-----|------|
            | 285 |  305 |
            | 356 |  352 |
            | 435 |  371 |
            | 355 |  313 |
            | 362 |  372 |
      |-----|-----|------|
        AVG | 359 |  343 |
      |-----|-----|------|
      

      处理file10.txt

            | ABC | ABC2 |
            |-----|------|
            | 256 |  251 |
            | 273 |  323 |
            | 355 |  347 |
            | 350 |  314 |
            | 315 |  286 |
      |-----|-----|------|
        AVG | 310 |  304 |
      |-----|-----|------|
      

      处理file100.txt

            | ABC | ABC2 |
            |-----|------|
            | 247 |  253 |
            | 239 |  246 |
            | 357 |  353 |
            | 387 |  334 |
            | 333 |  329 |
      |-----|-----|------|
        AVG | 313 |  303 |
      |-----|-----|------|
      

      处理file1000.txt

            | ABC  | ABC2  |
            |------|-------|
            |  977 |   924 |
            |  784 |   738 |
            |  818 |   764 |
            | 1142 |  1101 |
            |  975 |   903 |
      |-----|------|-------|
        AVG |  939 |   886 |
      |-----|------|-------|
      

      处理file10000.txt

            | ABC  | ABC2  |
            |------|-------|
            | 1150 |   748 |
            | 1147 |   811 |
            | 1069 |   654 |
            | 1181 |   799 |
            | 1234 |   805 |
      |-----|------|-------|
        AVG | 1156 |   763 |
      |-----|------|-------|
      

      处理file100000.txt

            | ABC  | ABC2  |
            |------|-------|
            | 5485 |  1769 |
            | 5268 |  1528 |
            | 5296 |  1555 |
            | 5308 |  1529 |
            | 5289 |  1553 |
      |-----|------|-------|
        AVG | 5329 |  1587 |
      |-----|------|-------|
      

      处理file1000000.txt

            | ABC   | ABC2   |
            |-------|--------|
            | 49034 |  12633 |
            | 52116 |  12484 |
            | 51643 |  12109 |
            | 52022 |  12359 |
            | 53145 |  12716 |
      |-----|-------|--------|
        AVG | 51592 |  12460 |
      |-----|-------|--------|
      

      file10000.txt 的区别变得显着。

      【讨论】:

        猜你喜欢
        • 2017-12-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-11-01
        • 2019-08-23
        • 1970-01-01
        相关资源
        最近更新 更多