Поздно на вечеринку ...
Хороший вопрос. Вы можете использовать этот код:
static void WriteABC2(string filename)
{
string tempfile = Path.GetTempFileName();
using (var writer = new FileStream(tempfile, FileMode.Create))
using (var reader = new FileStream(filename, FileMode.Open))
{
var stringBytes = Encoding.UTF8.GetBytes("A,B,C" + Environment.NewLine);
writer.Write(stringBytes, 0, stringBytes.Length);
reader.CopyTo(writer);
}
File.Copy(tempfile, filename, true);
File.Delete(tempfile);
}
Этот код основан на превосходном ответе Джейк , но я использую FileStream
вместо StreamWriter
и StreamReader
. Значительные улучшения производительности (даже в 4 раза быстрее по сравнению с моим тестом) при использовании FileStream
при обработке больших файлов. Просто чтобы быть немного яснее, я сделал несколько тестов и сообщил о результатах ниже.
Как я делал тесты
Я создал 7 файлов. Каждый файл содержит 10 ^ X строк и имеет имя file<line count>.txt
. Итак, список файлов:
| File name | Line count | File size |
|-----------------|------------|-----------|
| file1.txt | 1 | 66 byte |
| file10.txt | 10 | 678 byte |
| file100.txt | 100 | 6,72 KB |
| file1000.txt | 1000 | 68,2 KB |
| file10000.txt | 10000 | 692 KB |
| file100000.txt | 100000 | 6,85 MB |
| file1000000.txt | 1000000 | 69,5 MB |
Каждая строка каждого файла составлена следующим образом:
<line index starting from 0> - abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789
Например, первые две строки file10.txt
:
0 - abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789
1 - abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789
Я использовал приведенный ниже код для выполнения тестов и определения продолжительности выполнения функции:
var stopwatch = new Stopwatch();
long abcTotalDuration = 0;
long abc2TotalDuration = 0;
string fileInput = "file1.txt";
string outputFolder = "output";
for (int i = 0; i < 100; i++)
{
string filename1 = Path.Combine(outputFolder, Guid.NewGuid().ToString());
string filename2 = Path.Combine(outputFolder, Guid.NewGuid().ToString());
stopwatch.Restart();
WriteABC(fileInput, filename1);
stopwatch.Stop();
abcTotalDuration += stopwatch.ElapsedMilliseconds;
stopwatch.Restart();
WriteABC2(fileInput, filename2);
stopwatch.Stop();
abc2TotalDuration += stopwatch.ElapsedMilliseconds;
File.Delete(filename1);
File.Delete(filename2);
}
Console.WriteLine("ABC : " + abcTotalDuration.ToString());
Console.WriteLine("ABC2: " + abc2TotalDuration.ToString());
// Just to wake me up :-)
Console.Beep(800, 1000);
Console.ReadKey();
Тест состоит из добавления A,B,C(new line)
для каждого указанного файла. Результат сохраняется в отдельном файле (только для теста).
Я запускал код 5 раз для каждого входного файла (указан в переменной fileInput
). WriteABC
и WriteABC2
функции выполняются 100 раз каждый раз, когда я запускаю код.
Вот результаты (все в мс):
Обработка file1.txt
| ABC | ABC2 |
|-----|------|
| 285 | 305 |
| 356 | 352 |
| 435 | 371 |
| 355 | 313 |
| 362 | 372 |
|-----|-----|------|
AVG | 359 | 343 |
|-----|-----|------|
Обработка file10.txt
| ABC | ABC2 |
|-----|------|
| 256 | 251 |
| 273 | 323 |
| 355 | 347 |
| 350 | 314 |
| 315 | 286 |
|-----|-----|------|
AVG | 310 | 304 |
|-----|-----|------|
Обработка file100.txt
| ABC | ABC2 |
|-----|------|
| 247 | 253 |
| 239 | 246 |
| 357 | 353 |
| 387 | 334 |
| 333 | 329 |
|-----|-----|------|
AVG | 313 | 303 |
|-----|-----|------|
Обработка file1000.txt
| ABC | ABC2 |
|------|-------|
| 977 | 924 |
| 784 | 738 |
| 818 | 764 |
| 1142 | 1101 |
| 975 | 903 |
|-----|------|-------|
AVG | 939 | 886 |
|-----|------|-------|
Обработка file10000.txt
| ABC | ABC2 |
|------|-------|
| 1150 | 748 |
| 1147 | 811 |
| 1069 | 654 |
| 1181 | 799 |
| 1234 | 805 |
|-----|------|-------|
AVG | 1156 | 763 |
|-----|------|-------|
Обработка file100000.txt
| ABC | ABC2 |
|------|-------|
| 5485 | 1769 |
| 5268 | 1528 |
| 5296 | 1555 |
| 5308 | 1529 |
| 5289 | 1553 |
|-----|------|-------|
AVG | 5329 | 1587 |
|-----|------|-------|
Обработка file1000000.txt
| ABC | ABC2 |
|-------|--------|
| 49034 | 12633 |
| 52116 | 12484 |
| 51643 | 12109 |
| 52022 | 12359 |
| 53145 | 12716 |
|-----|-------|--------|
AVG | 51592 | 12460 |
|-----|-------|--------|
Разница становится заметной с file10000.txt
.