Как вставить строку в первой строке текстового файла? - PullRequest
14 голосов
/ 08 марта 2010

У меня есть тестовый файл, который содержит

1,2,3
2,3,4
5,6,7

Я хочу вставить это в первую строку: A,B,C

Так что я получаю:

A,B,C
1,2,3
2,3,4
5,6,7

Как я могу это сделать?

Ответы [ 6 ]

25 голосов
/ 08 марта 2010

Аналогично предыдущим ответам, но это иллюстрирует, как делать то, что вы хотите сделать, минимизируя потребление памяти. Невозможно прочитать весь файл, который вы хотите изменить, даже если вы откроете его в потоке чтения / записи, поскольку вы не можете «вставить» данные.

static void WriteABC(string filename)
{
    string tempfile = Path.GetTempFileName();
    using (var writer = new StreamWriter(tempfile))
    using (var reader = new StreamReader(filename))
    {
        writer.WriteLine("A,B,C");
        while (!reader.EndOfStream)
            writer.WriteLine(reader.ReadLine());
    }
    File.Copy(tempfile, filename, true);
}
3 голосов
/ 10 августа 2014

Я думаю, что этот ответ проще и быстрее:

public static void WriteToFile(string Path, string Text)
{
    string content = File.ReadAllText(Path);
    content = Text + "\n" + content;      
    File.WriteAllText(Path, content);
}

Тогда вы можете назвать это:

WriteToFile("yourfilepath", "A,B,C");
2 голосов
/ 08 марта 2010

Вот ссылка, объясняющая, как использовать классы TextReader (StreamReader) и TextWriter (StreamWriter) в C #.

http://www.csharpfriends.com/Articles/getArticle.aspx?articleID=132

Хотя это специфично для C #, подход может быть относительно одинаковым во многих языках.

(Примечание. Есть несколько способов сделать это, это одна из идей, которая быстро приходит на ум.)

По сути, вы можете прочитать содержимое вашего текстового файла в строку, найти начало этой строки, записать свою информацию (A, B, C с возвратом каретки или переводом строки), а затем записать эту информацию обратно в текстовый файл перезаписать исходное содержимое и сохранить.

1 голос
/ 09 февраля 2018

Поздно на вечеринку ...

Хороший вопрос. Вы можете использовать этот код:

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.

1 голос
/ 08 марта 2010

Вы не можете «вставить» что-либо в текстовый файл.

Вам придется

  • скопировать содержимое
  • инертные дополнительные данные в нужное время
  • закрыть файлы
  • удалить оригинал и переименовать новый в старое имя
0 голосов
/ 09 февраля 2018

@ Джейк: StringBuilder лучше и проще

public static void WriteToFile(string path, string text)
{
        StringBuilder stringBuilder = new StringBuilder();

        stringBuilder.AppendLine("a,b,c");
        stringBuilder.Append(File.ReadAllText(path)).AppendLine();
        File.WriteAllText(path, stringBuilder.ToString()); 
}

Edit: Но StringBuilder имеет ограничение буфера: максимальная емкость 2147483647

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