2012-02-07 3 views
1

Hei!Чтение нескольких файлов в потоке

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

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

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

Update:

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(); 
     } 

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

+0

Какую версию .Net вы используете? – svick

+0

Я использую: .net 3.5 –

+0

Почтовый индекс. Потоковые классы в .NET могут сделать намного лучше, чем это. Кроме того, в зависимости от версий .NET существуют методы для потоков, которые можно напрямую копировать из одного потока в другой через .CopyTo, которые не требуют посредника. – Joe

ответ

1

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

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)); 
    } 
} 
3

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

Похоже, вы хотите создать подкласс 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

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

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

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

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

Смежные вопросы