Чтение нескольких файлов в потоке - PullRequest
1 голос
/ 07 февраля 2012

Привет!

Как прочитать несколько текстовых файлов одновременно?То, что я хочу сделать, это прочитать ряд файлов и добавить их все в один большой файл.Конечно, я делаю это:

  1. взять каждый файл и открыть его с помощью StreamReader
  2. полностью прочитать StreamReader в StringBuilder и добавить его к текущему StreamBuilder
  3. проверьте, не превышен ли объем памяти, и если да, напишите StringBuilder в конце файла и очистите StrigBuilder

К сожалению, я заметил, что скорость чтения avg составляет всего 4 МБ / с.Я заметил, что когда я перемещаю файлы по диску, я получаю скорость 40 МБ / с.Я думаю о буферизации файлов в потоке и читаю их все сразу, как при записи.Есть идеи, как мне этого добиться?

Обновление:

 foreach (string file in System.IO.Directory.GetFiles(InputPath))
        {
            using (StreamReader sr = new StreamReader(file))
            {

                try
                {
                    txt = txt+(file + "|" + sr.ReadToEnd());
                }
                catch // out of memory exception 
                {
                    WriteString(outputPath + "\\" + textBox3.Text, ref txt);
                    //sb = new StringBuilder(file + "|" + sr.ReadToEnd());
                    txt = file + "|" + sr.ReadToEnd();
                }

            }

            Application.DoEvents();
        }

Вот как я это делаю сейчас.

Ответы [ 3 ]

3 голосов
/ 07 февраля 2012

С одной стороны, вам нужно различать потоки (двоичные данные) и StreamReader с или, в более общем смысле, TextReader с (текстовые данные).

Звучит так, как будто выхочу создать подкласс TextReader, который будет принимать (в своем конструкторе) набор TextReader параметров.Вам не нужно с нетерпением читать что-нибудь здесь ... но в методах Read, которые вы переопределяете, вы должны читать из "текущего" считывателя до тех пор, пока он не исчерпается, а затем начинать со следующего.Имейте в виду, что Read не имеет для заполнения предоставленного буфера - так что вы можете сделать что-то вроде:

while (true)
{
    int charsRead = currentReader.Read(buffer, index, size);
    if (charsRead != 0)
    {
        return charsRead;
    }
    // Adjust this based on how you store the readers...
    if (readerQueue.Count == 0)
    {
        return 0;
    }
    currentReader = readerQueue.Dequeue();
}

Я сильно подозреваю, что уже есть сторонние библиотекиимейте в виду, что для такого рода демультиплексирования ...

3 голосов
/ 07 февраля 2012

Если все, что вы делаете, это читаете файлы, а затем объединяете их вместе в новый файл на диске, вам может не понадобиться вообще писать код.Используйте команду копирования Windows:

C:\> copy a.txt+b.txt+c.txt+d.txt output.txt

Вы можете вызвать это через Process.Start, если хотите.

Это, конечно, предполагает, что вы не выполняете никакой пользовательской логики нафайлы или их содержимое.

1 голос
/ 07 февраля 2012

Это должно быть быстро (но оно загрузит все файлы в память, поэтому может не соответствовать всем потребностям):

string[] files = { @"c:\a.txt", @"c:\b.txt", @"c:\c.txt" };

FileStream outputFile = new FileStream(@"C:\d.txt", FileMode.Create);

using (BinaryWriter ws = new BinaryWriter(outputFile))
{
    foreach (string file in files)
    {
        ws.Write(System.IO.File.ReadAllBytes(file));
    }
}
...