Эффективное использование файла - PullRequest
1 голос
/ 01 июня 2010

У меня есть несколько файлов, содержимое которых нужно объединить в один файл. у меня есть следующий код, который делает это ... но он кажется довольно неэффективным с точки зрения использования памяти ... вы бы предложили лучший способ сделать это?

функция Util.MoveFile просто учитывает перемещение файлов между томами

   private void Compose(string[] files)
   {
       string inFile = "";
       string outFile = "c:\final.txt";

       using (FileStream fsOut = new FileStream(outFile + ".tmp", FileMode.Create))
       {
           foreach (string inFile in files)
           {
               if (!File.Exists(inFile))
               {
                   continue;
               }

               byte[] bytes;
               using (FileStream fsIn = new FileStream(inFile, FileMode.Open))
               {
                   bytes = new byte[fsIn.Length];
                   fsIn.Read(bytes, 0, bytes.Length);
               }

               //using (StreamReader sr = new StreamReader(inFile))
               //{
               //    text = sr.ReadToEnd();
               //}

               // write the segment to final file
               fsOut.Write(bytes, 0, bytes.Length);

               File.Delete(inFile);
           }
       }

       Util.MoveFile(outFile + ".tmp", outFile);

}

Ответы [ 2 ]

1 голос
/ 01 июня 2010

Иногда просто лучше вызвать функцию оболочки, чем переопределить функциональность. Как говорит Алан, вы можете использовать CAT в системах Unix или, возможно, в Windows вы можете использовать встроенный командный процессор

copy file1+file2+file3 concated_file
0 голосов
/ 01 июня 2010

Вы можете использовать меньшие буферы фиксированного размера, например:

byte[] bytes = new byte[8192]; // adjust this as needed
int bytesRead;
do {
    bytesRead = fsIn.Read(bytes, 0, bytes.Length);
    fsOut.Write(bytes, 0, bytesRead);
} while (bytesRead > 0);

Это довольно очевидно, за исключением последнего блока, так что в основном я передаю 8-байтовый массив в метод Read, который возвращает количество байтов, которые он фактически прочитал. Поэтому при вызове Write я передаю это значение, которое находится где-то между 0 и 8192. Другими словами, в последнем блоке, даже если я передаю байтовый массив из 8192 байтов, bytesRead может быть только 10, в этом случае необходимо записать только первые 10 байтов.

EDIT

Я отредактировал свой ответ, чтобы сделать это немного по-другому. Вместо того, чтобы использовать позицию входного файла, чтобы определить, когда выйти из цикла, я проверяю, является ли bytesRead больше нуля. Этот метод работает с любым видом потока для потокового копирования, включая потоки, которые не имеют фиксированной или известной длины.

...