Чтение файла линию за линией в C#

Существует несколько причин хранения исходного msi:

  • деинсталлятор использует его для знания, какие файлы и ключи реестра были установлены и удостоверяются, что все очищены.
  • msi может содержать код для специальных действий удаления, которые должны быть выполнены.
  • Это позволяет Вам, делают к операции 'восстановления' из меню Add/Remove Programs, независимо от того, сохранили ли Вы файл установки сами.

нормальный способ вещей состоит в том, чтобы Windows сохранил файл кэшируемым для Вас, таким образом, Вы не должны думать об этом. Посмотрите свой %WINDIR %\Installer\папка. Единственная причина это попросило бы у Вашего исходного msi, состоит в том, если что-то неправильно с сохраненным файлом. Это обращается к большинству Ваших проблем, хотя это действительно повышает новый один (дисковое пространство).

56
задан Peter Mortensen 20 January 2017 в 16:42
поделиться

4 ответа

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

static IEnumerable<SomeType> ReadFrom(string file) {
    string line;
    using(var reader = File.OpenText(file)) {
        while((line = reader.ReadLine()) != null) {
            SomeType newRecord = /* parse line */
            yield return newRecord;
        }
    }
}

или, чтобы порадовать Джона:

static IEnumerable<string> ReadFrom(string file) {
    string line;
    using(var reader = File.OpenText(file)) {
        while((line = reader.ReadLine()) != null) {
            yield return line;
        }
    }
}
...
var typedSequence = from line in ReadFrom(path)
                    let record = ParseLine(line)
                    where record.Active // for example
                    select record.Key;

, тогда у вас есть ReadFrom (...) как последовательность с отложенным вычислением без буферизации, идеально подходящая для , где и т. Д.

Обратите внимание, что если вы используете OrderBy или стандартный GroupBy , он необходимо буферизовать данные в памяти; Если вам нужна группировка и агрегация, в PushLINQ есть необычный код, позволяющий выполнять агрегирование данных, но отбрасывать их (без буферизации). Объяснение Джона здесь .

94
ответ дан 26 November 2019 в 17:16
поделиться

Проще прочитать строку и проверить, является ли она нулевой, чем постоянно проверять наличие EndOfStream.

Однако у меня также есть класс LineReader в MiscUtil , который делает все это намного проще - в основном он предоставляет файл (или Func как IEnumerable , который позволяет вам делать Над ним работает LINQ. Таким образом, вы можете делать такие вещи, как:

var query = from file in Directory.GetFiles("*.log")
            from line in new LineReader(file)
            where line.Length > 0
            select new AddOn(line); // or whatever

В основе LineReader лежит реализация IEnumerable .GetEnumerator :

public IEnumerator<string> GetEnumerator()
{
    using (TextReader reader = dataSource())
    {
        string line;
        while ((line = reader.ReadLine()) != null)
        {
            yield return line;
        }
    }
}

Почти все остальное. источник просто предоставляет гибкие способы настройки dataSource (который является Func ).

23
ответ дан 26 November 2019 в 17:16
поделиться

ПРИМЕЧАНИЕ : вам нужно остерегаться решения IEnumerable , так как оно приведет к тому, что файл будет открыт на время обработки.

Например, с ответом Марка Грейвелла:

foreach(var record in ReadFrom("myfile.csv")) {
    DoLongProcessOn(record);
}

файл будет оставаться открытым в течение всей обработки.

1
ответ дан 26 November 2019 в 17:16
поделиться

Спасибо всем за ответы! Я решил использовать смесь, в основном сосредоточившись на Марке, так как мне нужно будет читать только строки из файла. Думаю, вы можете утверждать, что разделение необходимо везде, но жизнь слишком коротка!

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

Наконец, я заметил, что все вы использовали строчные буквы. Я знаю, что в Java есть разница между строкой с заглавной и без заглавной буквы, но я думал, что в C # строчная строка была просто ссылкой на строку с заглавной буквы?

public void Load(AddonCollection<T> collection)
{
    // read from file
    var query =
        from line in LineReader(_LstFilename)
        where line.Length > 0
        select CreateAddon(line);

    // add results to collection
    collection.AddRange(query);
}

protected T CreateAddon(String line)
{
    // create addon
    T addon = new T();
    addon.Load(line, _BaseDir);

    return addon;
}

protected static IEnumerable<String> LineReader(String fileName)
{
    String line;
    using (var file = System.IO.File.OpenText(fileName))
    {
        // read each line, ensuring not null (EOF)
        while ((line = file.ReadLine()) != null)
        {
            // return trimmed line
            yield return line.Trim();
        }
    }
}
0
ответ дан 26 November 2019 в 17:16
поделиться
Другие вопросы по тегам:

Похожие вопросы: