C # как разбить текстовый файл на несколько файлов - PullRequest
1 голос
/ 03 сентября 2011

Как разделить один текстовый файл с 1000 строками на несколько файлов меньшего размера, например, по 300 строк?Помните, что в исходном файле может быть больше или меньше тысячи строк.

file1.txt 300 lines -> rest
file2.txt 300 lines -> rest
file3.txt 300 lines -> rest
file4.txt 100 lines 

Я пробовал следующее, но оно не работает.

int counter = 0;
string line;

string lineoutput = (current_dir + "\\" + DateTime.Now.ToString("HHmmss") + ".txt");

System.IO.StreamReader inputfile;

inputfile = new System.IO.StreamReader(new_path);
while ((line = inputfile.ReadLine()) != null)
{
    System.IO.StreamWriter file = new System.IO.StreamWriter(current_dir + "\\" + DateTime.Now.ToString("HHmmss") + ".txt", true);

    string _replaceBackspace = ReplaceBackspace(read_file.ReadLine().ToLower());

    using (StreamWriter writer = new StreamWriter(lineoutput, true))
    {
        if (counter == 5000)
        {
            counter = 0;
            lineoutput = (current_dir + "\\" + DateTime.Now.ToString("HHmmss") + ".txt");
        }
        writer.WriteLine(line.ToLower());
    }
    counter++;
}

Ответы [ 5 ]

7 голосов
/ 03 сентября 2011

Простейший случай:

        var reader = File.OpenText(infile);
        string outFileName = "file{0}.txt";
        int outFileNumber = 1;
        const int MAX_LINES = 300;
        while (!reader.EndOfStream)
        {
            var writer = File.CreateText(string.Format(outFileName, outFileNumber++));
            for (int idx = 0; idx < MAX_LINES; idx++)
            {
                writer.WriteLine(reader.ReadLine());
                if (reader.EndOfStream) break;
            }
            writer.Close();
        }
        reader.Close();
6 голосов
/ 03 сентября 2011
string baseName = current_dir + "\\" + DateTime.Now.ToString("HHmmss") + ".";

StreamWriter writer = null;
try
{
    using (StreamReader inputfile = new System.IO.StreamReader(new_path))
    {
        int count = 0;
        string line;
        while ((line = inputfile.ReadLine()) != null)
        {

            if (writer == null || count > 300)
            {
                if (writer != null)
                {
                    writer.Close();
                    writer = null;
                }

                writer = new System.IO.StreamWriter(baseName + count.ToString() + ".txt", true);

                count = 0;
            }

            writer.WriteLine(line.ToLower());

            ++count;
        }
    }
}
finally
{
    if (writer != null)
        writer.Close();
}
5 голосов
/ 03 сентября 2011

Зацикливайтесь на File.ReadLines(path) и записывайте каждую строку в StreamWriter.

Держите счетчик, и каждый раз, когда он достигает 300, закрывайте StreamWriter и открывайте новый.

2 голосов
/ 03 сентября 2011

Как и SLaks ответ, вы также можете сделать это, используя методы расширения Skip и Take в System.Linq

string[] ss = File.ReadAllLines(@"path to the file");

int cycle = 1;
int chunksize = 300;

var chunk = ss.Take(chunksize);
var rem = ss.Skip(chunksize);

while (chunk.Take(1).Count() > 0)
{
    string filename = "file" + cycle.ToString() + ".txt";
    using (StreamWriter sw = new StreamWriter(filename))
    {
        foreach(string line in chunk)
        {
            sw.WriteLine(line);
        }
    }
    chunk = rem.Take(chunksize);
    rem = rem.Skip(chunksize);
    cycle++;
}
0 голосов
/ 13 июля 2018

Следуя ответу от bigtbl, я добавил для случая генерации серии CSV сохранение первой строки в качестве заголовка для каждого файла.MAX_LINES включает строку заголовка для общего количества, что является причиной для start_idx.

public static void SplitFil(int rows, string inputFile) {
      int outFileNumber = 1;      
      const int MAX_LINES = 50000;      
      string header = "";
      if (GetFileSize(inputFile) > MAX_LINES) {
        var reader = File.OpenText(inputFile);               
        while (!reader.EndOfStream)
        {
          var start_idx = 0;          
          var writer = File.CreateText($"filename_{outFileNumber}.csv");
          if (outFileNumber > 1) {
            writer.WriteLine(header);
            start_idx = 1;
          }            
          for (int idx = start_idx; idx < MAX_LINES; idx++)
          { 
            var row = reader.ReadLine();
            if (idx == 0 && outFileNumber == 1) header = row;
            writer.WriteLine(row);
            if (reader.EndOfStream) break;
          }
          writer.Close();
          outFileNumber++;
        }
        reader.Close();
      }
    }
...