Как лучше всего заменить текст в файле с помощью C # / .NET? - PullRequest
7 голосов
/ 13 мая 2009

У меня есть текстовый файл, который записывается как часть очень большого извлечения данных. Первая строка текстового файла - это количество извлеченных «учетных записей».

Из-за природы этого извлечения это число неизвестно до самого конца процесса, но файл может быть большим (несколько сотен мегабайт).

Как лучше всего в C # / .NET открыть файл (в данном случае простой текстовый файл) и заменить данные, которые находятся в первой «строке» текста?

ВАЖНОЕ ПРИМЕЧАНИЕ : - Мне не нужно заменять «фиксированное количество байтов» - это было бы легко. Проблема в том, что данные, которые нужно вставить в начало файла, являются переменными.

ВАЖНОЕ ПРИМЕЧАНИЕ 2 : - Несколько человек спрашивали о / упомянули о простом сохранении данных в памяти и последующей их замене ... однако об этом совершенно не может быть и речи. Причина, по которой этот процесс обновляется, заключается в том, что иногда происходит сбой при загрузке нескольких гигабайт в память.

Ответы [ 6 ]

4 голосов
/ 13 мая 2009

Если вы можете, вы должны вставить заполнитель, который вы перезаписываете в конце с фактическим числом и пробелами.

Если это не вариант, сначала запишите ваши данные в файл кэша. Когда вы знаете фактическое число, создайте выходной файл и добавьте данные из кэша.

3 голосов
/ 13 мая 2009

ЛУЧШИЙ очень субъективен. Для любого небольшого файла вы можете легко открыть весь файл в памяти и заменить то, что вы хотите, используя строку replace, а затем переписать файл.

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

Вы проверяли этот наивный подход? Вы видели реальную проблему с этим?

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

 TYPE temp.txt >> outfile.txt
2 голосов
/ 19 мая 2009

Мне кажется, правильно ли я понял вопрос?

Как лучше всего в C # / .NET открыть файл (в данном случае простой текстовый файл) и заменить данные, которые находятся в первой «строке» текста?

Как насчет размещения в верхней части файла токена {UserCount} при его первом создании.

Затем используйте TextReader для чтения файла построчно. Если это первая строка, найдите {UserCount} и замените его своим значением. Запишите каждую строку, которую вы прочитали, используя TextWriter

Пример:

    int lineNumber = 1;
    int userCount = 1234;
    string line = null;

    using(TextReader tr = File.OpenText("OriginalFile"))
    using(TextWriter tw = File.CreateText("ResultFile"))
    {

        while((line = tr.ReadLine()) != null)
        {
            if(lineNumber == 1)
            {
                line = line.Replace("{UserCount}", userCount.ToString());
            }

            tw.WriteLine(line);
            lineNumber++;
        }

    }
2 голосов
/ 13 мая 2009

Мне не нужно заменять «исправленный количество байтов "

Ты уверен? Если вы записали большое число в первую строку файла (UInt32.MaxValue или UInt64.MaxValue), то, когда вы найдете правильное действительное число, вы можете заменить это число байтов на правильное число, но оставив его дополненным нулями так что это все еще допустимое целое число. например,

Replace  999999 - your "large number placeholder"
With     000100 - the actual number of accounts
1 голос
/ 22 мая 2009

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

Однако в вашей ситуации вы хотите создать файл, и в процессе создания вернитесь к началу и запишите количество пользователей. Это сделает именно это.

Вот один из способов сделать это, чтобы вам не пришлось писать временный файл.

    private void WriteUsers()
    {   
        string userCountString = null;
        ASCIIEncoding enc = new ASCIIEncoding();
        byte[] userCountBytes = null;
        int userCounter = 0;

        using(StreamWriter sw = File.CreateText("myfile.txt"))
        {
            // Write a blank line and return
            // Note this line will later contain our user count.
            sw.WriteLine();

            // Write out the records and keep track of the count 
            for(int i = 1; i < 100; i++)
            {
                sw.WriteLine("User" + i);
                userCounter++;
            }

            // Get the base stream and set the position to 0
            sw.BaseStream.Position = 0;

            userCountString = "User Count: " + userCounter;

            userCountBytes = enc.GetBytes(userCountString);

            sw.BaseStream.Write(userCountBytes, 0, userCountBytes.Length);
        }

    }
1 голос
/ 13 мая 2009

Если извлеченный файл занимает всего несколько сотен мегабайт, то вы можете легко хранить весь текст в памяти до завершения извлечения. Затем вы можете записать выходной файл как последнюю операцию, начиная с количества записей.

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