【问题标题】:Split a text file into smaller files将文本文件拆分为较小的文件
【发布时间】:2012-07-19 12:26:50
【问题描述】:

我有一个 1000 000 条记录的文本文件,所以我想将文件分成许多文件,每个文件有 100 条记录。这是我使用 listbox1 来控制文件的代码。代码运行正常,但丢失的记录较少。

private void WriteToFile()
    {
        int RowCount = listBox1.Items.Count;
        string FileName = "C:\\Users\\bbdnet0986\\Documents\\MyExpotedQADATA";
        StreamWriter sw = new StreamWriter(FileName + ".txt");
        int inc = 0;
        int counter = 0;
        //StreamWriter sw = new StreamWriter(FileName+inc + ".txt");
        for (int i = 0; i < listBox1.Items.Count; i++)
        {
             sw.WriteLine(listBox1.Items[i].ToString());
             string me = listBox1.Items[i].ToString();

             if (RowCount > 100)
             {

                 listBox2.Items.Add(listBox1.Items[counter].ToString());
                 counter++;
                 if (counter == 100)
                 {

                     inc++;
                     sw = new StreamWriter(FileName + inc + ".txt");


                     RowCount = RowCount - counter;
                     counter = 0;

                 }
             }

             else
             {
                  sw.WriteLine(listBox1.Items[i].ToString());
             }

         }
         sw.Close();
    }

【问题讨论】:

  • 列表框不太适合或不打算容纳 100 万个项目。

标签: c#


【解决方案1】:

在这一行:

sw = new StreamWriter(FileName + inc + ".txt");

你需要 .Flush() 前一个 sw。写入器已缓冲,这就是缺少某些记录的原因。

【讨论】:

    【解决方案2】:

    我不确定您的问题与您的ListBox 有什么关系,所以我将向您展示一个解决方案,它每 100 行从一个大文件创建文件。

    LinqEnumerable.GroupBy 很容易:

    int maxLineCount = 100;
    FileInfo file = new FileInfo(hugeFilePath);
    
    var fileGroups = File.ReadLines(file.FullName)
        .Select((l, i) => new { Line = l, Index = i })
        .GroupBy(x => x.Index / maxLineCount)
        .Select(grp => new { FileIndex = grp.Key, Lines = grp.Select(x => x.Line)});
    
    foreach (var grp in fileGroups)
    {
        var fileName = "File" + grp.FileIndex;
        var path = Path.Combine(@"C:\Temp\Test", fileName + file.Extension).ToString();
        File.WriteAllLines(path, grp.Lines);
    }
    

    请注意,File.ReadLines 流式传输行而不是将所有行加载到内存中。

    【讨论】:

      【解决方案3】:

      这里有一个更简单的方法:

      private void WriteToFile() 
      { 
          // get an array of strings - you'll find out way :)
          string[] items = listBox1.Items.Cast<string>().ToArray();
      
          // this would also work with ReadAllLines()
          string[] items = File.ReadAllLines("Your original file");
      
          // path + filename prefix
          string fileNamePattern = "C:\\Users\\bbdnet0986\\Documents\\MyExpotedQADATA{0}.txt"; 
      
          // blocks of 100
          string[] buffer;
          for(int i = 0; i < items.Length; i += 100)
          {
              // slice the string array into 100 string blocks
              buffer = items.Slice(i, 100);
      
              // output the block of strings
              File.WriteAllLines(string.Format(fileNamePattern, i), buffer);
          }
      }
      

      切片扩展:

          public static T[] Slice<T>(this T[] source, int index, int length)
          {
              T[] slice = new T[length];
              Array.Copy(source, index, slice, 0, length);
              return slice;
          }
      

      【讨论】:

      • 这不必要地一次将 1000000 行加载到内存中。
      • @TimSchmelter - 另一种方法,因为您已经获得了最佳答案。另请注意,我的解决方案比 LINQ 和 .NET 2.0-3.5 (VS 2008) 友好:) 但是,我想我可以使用 FileStream 代替。
      猜你喜欢
      • 2012-06-26
      • 1970-01-01
      • 1970-01-01
      • 2013-07-31
      • 1970-01-01
      • 2011-07-13
      • 1970-01-01
      • 2019-10-02
      • 1970-01-01
      相关资源
      最近更新 更多