Какой самый быстрый способ объединить три файла в C #? - PullRequest
19 голосов
/ 14 января 2009

Мне нужно объединить 3 файла с помощью C #. Файл заголовка, содержимое и файл нижнего колонтитула, но я хочу сделать это настолько круто, насколько это возможно.

Cool = действительно маленький код или очень быстрый (не ассемблерный код).

Ответы [ 7 ]

30 голосов
/ 06 июня 2012

Я поддерживаю Мехрдада Афшари, поскольку его код точно такой же, как и в System.IO.Stream.CopyTo . Я все еще удивляюсь, почему он не использовал эту же функцию вместо того, чтобы переписать ее реализацию.

        string[] srcFileNames = { "file1.txt", "file2.txt", "file3.txt" };
        string destFileName = "destFile.txt";

        using (Stream destStream = File.OpenWrite(destFileName))
        {
            foreach (string srcFileName in srcFileNames)
            {
                using (Stream srcStream = File.OpenRead(srcFileName))
                {
                    srcStream.CopyTo(destStream);
                }
            }
        }

Согласно дизассемблеру ( ILSpy ) размер буфера по умолчанию равен 4096. Функция CopyTo перегружена, что позволяет указать размер буфера в случае, если вас не устраивают 4096 байт.

24 голосов
/ 14 января 2009
void CopyStream(Stream destination, Stream source) {
   int count;
   byte[] buffer = new byte[BUFFER_SIZE];
   while( (count = source.Read(buffer, 0, buffer.Length)) > 0)
       destination.Write(buffer, 0, count);
}


CopyStream(outputFileStream, fileStream1);
CopyStream(outputFileStream, fileStream2);
CopyStream(outputFileStream, fileStream3);
7 голосов
/ 14 января 2009

Если ваши файлы текстовые и не большие, то есть что-то, что можно сказать о простом, очевидном коде. Я бы использовал следующее.

File.ReadAllText("file1") + File.ReadAllText("file2") + File.ReadAllText("file3");

Если ваши файлы представляют собой большие текстовые файлы и вы используете Framework 4.0, вы можете использовать File.ReadLines, чтобы избежать буферизации всего файла.

File.WriteAllLines("out", new[] { "file1", "file2", "file3" }.SelectMany(File.ReadLines));

Если ваши файлы бинарные, см. Ответ Мехрдада

6 голосов
/ 14 января 2009

Другой способ ... как насчет того, чтобы позволить ОС сделать это за вас?:

ProcessStartInfo psi = new ProcessStartInfo("cmd.exe", 
        String.Format(@" /c copy {0} + {1} + {2} {3}", 
            file1, file2, file3, dest));
psi.UseShellExecute = false;
Process process = Process.Start(psi);
process.WaitForExit();
3 голосов
/ 14 января 2009

Вы имеете в виду 3 текстовых файла ?? Результат должен быть снова файлом?

Как насчет чего-то вроде:

string contents1 = File.ReadAllText(filename1);
string contents2 = File.ReadAllText(filename2);
string contents3 = File.ReadAllText(filename3);

File.WriteAllText(outputFileName, contents1 + contents2 + contents3);

Конечно, с помощью StringBuilder и немного дополнительных умов вы можете легко расширить это для обработки любого количества входных файлов: -)

Приветствия

1 голос
/ 14 января 2009

Если вы находитесь в среде Win32 , наиболее эффективным решением может быть использование функции Win32 API «WriteFile». В VB 6 есть пример , но переписать его на C # несложно.

0 голосов
/ 14 января 2009

Я не очень хорошо знаю C # - вы можете вызвать оболочку оттуда? Можете ли вы сделать что-то вроде

 system("type file1 file2 file3 > out"); 

Я считаю, что асимптотически это должно быть очень быстро.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...