Как считать весь файл в строку c
Перейти к содержимому

Как считать весь файл в строку c

  • автор:

Как прочитать содержимое файла в string

Vladimir Gamalyan's user avatar

Ещё несколько вариантов (в теории, по возрастанию скорости):

Vladimir Gamalyan's user avatar

Для начала, ofstream предназначен для вывода в файл, для ввода из файла используйте ifstream . Проще всего читать построчно:

Не забудьте, что std::getline не сохраняет \n в конце строки, так что при необходимости добавьте его сами.

VladD's user avatar

Дизайн сайта / логотип © 2023 Stack Exchange Inc; пользовательские материалы лицензированы в соответствии с CC BY-SA . rev 2023.3.11.43304

Нажимая «Принять все файлы cookie» вы соглашаетесь, что Stack Exchange может хранить файлы cookie на вашем устройстве и раскрывать информацию в соответствии с нашей Политикой в отношении файлов cookie.

Как прочитать весь файл в строку с помощью C #?

Каков самый быстрый способ чтения текстового файла в строковой переменной?

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

16 ответов

Сравнительное сравнение File.ReadAllLines vs StreamReader ReadLine с Обработка файлов С#

Изображение 106971

Результаты. StreamReader намного быстрее для больших файлов с 10 000+ линий, но разница для меньших файлов незначительна. Как всегда, планировать различные размеры файлов и использовать File.ReadAllLines только тогда, когда производительность не является критичной.

Подход StreamReader

Поскольку подход File.ReadAllText был предложен другими, вы также можете попробовать быстрее (я не тестировал количественное влияние производительности, но он, по-видимому, быстрее, чем File.ReadAllText (см. сравнение ниже)). Разница в производительности будет видна только в случае больших файлов.

Сравнение File.Readxxx() vs StreamReader.Readxxx()

Просмотр индикативного кода через ILSpy Я нашел следующее о File.ReadAllLines , File.ReadAllText .

  • File.ReadAllText — использует StreamReader.ReadToEnd внутренне
  • File.ReadAllLines — также использует StreamReader.ReadLine внутренне с дополнительными накладными расходами на создание List<string> для возврата в виде строк чтения и циклирования до конца файла.

Таким образом, оба метода — дополнительный уровень удобства, построенный поверх StreamReader . Это видно из показательного тела метода.

File.ReadAllText() реализация как декомпилированная ILSpy

Некоторые важные замечания:

Этот метод открывает файл, читает каждую строку файла, а затем добавляет каждая строка как элемент строки. Затем он закрывает файл. Линия определяется как последовательность символов, за которой следует возврат каретки (‘\ r’), прямой канал (‘\n’) или возврат каретки сразу же по линии. Полученная строка не содержит завершающего возврат каретки и/или подача строки.

Этот метод пытается автоматически определить кодировку файла основанный на наличии знаков порядка байтов. Форматы кодирования UTF-8 и UTF-32 (как для большого, так и для малознакового) может быть обнаружен.

Использовать метод ReadAllText (String, Encoding) при чтении файлы, которые могут содержать импортированный текст, поскольку непризнанные символы могут быть неправильно прочитаны.

Этот дескриптор файла может быть закрыт этим методом, даже если исключения возникают

string text = File.ReadAllText(«Path»); у вас есть весь текст в одной строковой переменной. Если вам нужна каждая строка отдельно, вы можете использовать это:

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

@Извините. Это цитата MSDN Microsoft

В этом эксперименте будут сравниваться два класса. Класс StreamReader и FileStream будет направлен на чтение двух файлов из 10K и 200K полностью из каталога приложений.

Изображение 106972

FileStream , очевидно, быстрее в этом тесте. Требуется дополнительно на 50% больше времени для StreamReader , чтобы прочитать маленький файл. Для большого файла это заняло дополнительно 27% времени.

StreamReader специально ищет разрывы строк, а FileStream — нет. Это потребует некоторого дополнительного времени.

В зависимости от того, что приложение должно делать с разделом данных, может потребоваться дополнительный синтаксический анализ, который потребует дополнительного времени обработки. Рассмотрим сценарий, в котором файл имеет столбцы данных, а строки CR/LF ограничены. StreamReader будет работать по строке текста, ищущего CR/LF , а затем приложение будет выполнять дополнительный синтаксический анализ, ищущий конкретное местоположение данных. (Вы считали, что String. SubString поставляется без цены?)

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

Методы класса StreamReader

Согласно документации методы Close() и Dispose() имеют следующую общую форму:

Метод Close() закрывает объект типа StreamReader и базовый поток а также освобождает любые системные ресурсы, ассоциированные с этим объектом.

Метод Dispose() закрывает базовый поток, освобождает неуправляемые (unmanaged) ресурсы и позволяет по выбору освобождать управляемые (managed) ресурсы с помощью параметра disposing . Если disposing = true , то освобождаются и управляемые и неуправляемые ресурсы. Если disposing = false , то освобождаются только неуправляемые ресурсы.

Вызвать метод Dispose() с параметром не удастся, поскольку он объявлен как protected . В классе TextReader есть вариант метода Dispose() без параметров, который наследуется классом StreamReader . Этот метод имеет объявления

и может быть вызван из экземпляра типа StreamReader .

Использование метода Close() выглядит следующим образом

Аналогично может быть вызван метод Dispose()

2.2. Метод Peek()

Метод Peek() используется, когда нужно заранее определить следующий символ, который будет прочитан из потока. Метод возвращает следующий символ потока но не перемещает указатель чтения из файла. Согласно документации, объявление метода имеет вид:

Метод возвращает целое число, представляющее следующий символ. Если нет символов в потоке или поток не поддерживает поиск, то метод возвращает -1.

Пример. В примере используется метод Peek() для проверки того, достигнут конец файла. На экран выводится содержимое файла myfile1.txt .

2.3. Метод Read() . Чтение одиночного символа

Для чтения символа из потока ввода используется метод Read() , который имеет следующее объявление

Метод считывает следующий символ из потока ввода и сдвигает указатель чтения из файла на один символ. Метод возвращает прочитанный символ, представленный как тип System.Int32 или -1, если символ не удалось прочитать.
Если файла не существует, генерируется исключение типа System.IOException .

Пример. В примере, с помощью метода Read() происходит посимвольно чтение файла и вывод его содержимого на экран.

2.4. Метод Read(char[], int, int) . Чтение группы символов в буфер

Другая перегруженная реализация метода Read() предназначена для чтения набора символов в указанный буфер и имеет следующее объявление

  • buffer — массив символов, в который считывается содержимое текущего потока ввода. Символы потока записываются в позициях от index до index + count-1 массива buffer ;
  • index — позиция в буфере, с которой начинается считывание;
  • count — максимальное количество считываемых символов.

Метод возвращает количество реально прочитанных символов. Значение прочитанных символов колеблется в пределах от 0 до count . Если не удалось прочитать символы, метод возвращает 0.

При использовании метода обрабатываются следующие исключения:

  • System.ArgumentException — случай, когда длина buffer минус index является меньше чем count ;
  • System.ArgumentNullException — buffer равен null ;
  • System.ArgumentOutOfRangeException — значение index или count отрицательны;
  • System.IO.IOException — случай, когда поток закрыт.

Пример. В примере считывается файл порциями по 10 символов с помощью метода Read() .

2.5. Метод ReadBlock() . Прочитать набор символов из файлового потока

Метод ReadBlock() считывает набор символов из потока ввода в указанный участок памяти. Метод имеет следующее объявление

  • buffer – массив, в который считываются символы из потока. В массиве символы записываются начиная с позиции index до позиции ( index + count — 1 );
  • index — начальная позиция в массиве, в которую считываются символы из потока;
  • count — максимальное количество считываемых символов.

При использовании метода могут быть сгенерированы исключения следующих типов:

  • System.ArgumentException — случай, когда длина buffer минус index является меньше чем count;
  • System.ArgumentNullException — buffer равен null ;
  • System.ArgumentOutOfRangeException — значение index или count есть отрицательными;
  • System.IO.IOException — случай, когда поток закрыт;
  • System.ObjectDisposedException — случай, когда поток StreamReader закрыт.

Пример. В примере считывается содержимое файла в буфер buffer за один раз. Для определения длины файла используется класс FileInfo .

2.6. Метод ReadLine() . Чтение строки

Метод ReadLine() используется для чтения строки из файлового потока. Согласно документации, метод имеет следующее объявление

Метод возвращает строку символов из текущего файлового потока. Если достигнут конец потока, метод возвращает null .

При использовании метода могут возникать исключения следующих типов:

  • System.OutOfMemoryException — случай, когда недостаточно памяти для выделения ее в возвращаемую строку;
  • System.IO.IOException — ошибка ввода/вывода.

Пример. В примере построчно считывается текстовый файл и выводится на экран.

2.7. Метод ReadToEnd()

Метод ReadToEnd() считывает все символы с текущей позиции чтения до конца потока. Объявления метода имеет вид

Метод возвращает поток в виде строки. Если текущая позиция указывает на конец потока, метод возвращает пустую строку «» .

При использовании метода могут возникать исключения следующих типов:

  • System.OutOfMemoryException — случай, когда недостаточно памяти для выделения ее под выделяемую строку;
  • System.IO.IOException — ошибка ввода/вывода.

Пример. В примере выводится содержимое текстового файла на экран. Файл считывается в строку методом ReadToEnd() .

3. Свойства класса StreamReader
3.1. Свойство BaseStream . Получить ссылку на базовый поток

С помощью свойства BaseStream можно получить ссылку на базовый поток Stream . Объявление свойства следующее

Пример. В примере определяется размер файла в байтах с помощью ссылки на базовый поток.

3.2. Свойство CurrentEncoding . Получить кодировку потока

Свойство CurrentEncoding позволяет получить объект, содержащий данные о текущей кодировке в потоке. Объявление свойства следующее:

Чтобы использовать свойство можно написать примерно следующий код

3.3. Свойство EndOfStream . Определить окончание потока

Свойство EndOfStream предназначено для определения того, указывает ли текущая позиция потока на конец потока. Объявление свойства имеет вид

Свойство возвращает true , если текущая позиция потока указывает на его конец. В противном случае свойство возвращает false .

При использовании свойства может возникнуть исключение типа System.ObjectDisposedException .

Пример. В примере осуществляется посимвольно чтение из файла до тех пор, пока не будет достигнут конец файла. Конец файла определяется с помощью свойства EndOfStream .

Чтение и запись данных в файл

Операции чтения и записи данных в файлы в принципе очень просты, однако выполняются они не через объекты DirectoryInfo и FileInfo. В .NET Framework 4 это делается через объект File. Позже будет показано, как их выполнять с помощью других классов, представляющих обобщенную концепцию потока (stream).

До появления .NET Framework 2.0 вокруг того, как следует производить чтение и запись данных в файлы, велось много споров. Классы из .NET Framework можно было использовать, но такой подход не был простым. В версии .NET Framework 2.0 класс File был расширен; с его помощью стало возможным выполнение операций чтения и записи данных в файлы с помощью всего одной строки кода. То же самое доступно и в .NET Framework 4.

Чтение из файла

Рассмотрим пример чтения файла, создав приложение WPF, которое содержит обычное текстовое поле, кнопку и многострочное текстовое поле. В конечном итоге должна получиться форма, подобная показанной ниже. Используйте следующую разметку:

При построении данного приложения первым шагом является добавление оператора using для включения пространства имен System.IO. После этого с помощью события buttonRead_Click кнопки Прочитать многострочное текстовое поле заполняется содержимым файла. Затем к содержимому файла можно получать доступ методом File.ReadAllText(). Как не трудно заметить, чтение файла осуществляется с помощью единственного оператора.

Метод ReadAllText() открывает указанный файл, считывает его содержимое и затем закрывает его. Возвращаемое значение метода ReadAllText() представляет собой строку, в которой хранится все содержимое указанного файла. Результат может выглядеть примерно так, как показано на рисунке:

Считывание содержимого файла

Для открытия файлов и работы с ними предназначены также методы ReadAllBytes и ReadAllLines. Метод ReadAllBytes позволяет открывать двоичные файлы и считывать их содержимое в байтовый массив. Упомянутый выше метод ReadAllText возвращает все содержимое файла в виде одной строки. Такое поведение не всегда подходит. Вместо этого может требоваться работать с содержимым файла в построчной манере, т.е. строка за строкой. Для этого служит метод ReadAllLines, который возвращает массив строк с содержимым файла.

Запись в файл

Помимо чтения, в .NET Framework существенно упрощает также и запись данных в файлы. Вдобавок к методам для чтения файлов ReadAllText(), ReadAllLines() и ReadAllBytes() , в ней предлагаются методы, предназначенные для записи данных в файлы — WriteAllText() , WriteAllBytes() иWriteAllLines().

Рассмотрим пример, основанный на том же проекте WPF, но на этот раз многострочное текстовое поле будет использоваться для ввода данных в файл. Код обработчика событий buttonRead_Click теперь должен выглядеть следующим образом:

Скомпонуйте и запустите приложение. Введите в первом текстовом поле значение С:\Testing.txt, а во втором — какой-нибудь текст, после чего щелкните на кнопке. Внешне ничего не произойдет, однако, если заглянуть после этого в корневой каталог на диске С:, то можно будет обнаружить там файл Testing.txt с содержимым, которое было введено во втором текстовом поле.

Метод WriteAllText() создал в указанном каталоге новый текстовый файл, поместил в него предоставленное в поле содержимое и закрыл файл. Неплохо для всего одной строки кода. Если запустить приложение снова и указать тот же файл (Testing.txt), но задать новое содержимое для него, щелчок на кнопке опять заставит приложение выполнить ту же операцию. Новое содержимое не добавляется к старому, а полностью заменяет его. Методы WriteAllText(), WriteAllBytes() и WriteAllLines() перезаписывают предыдущее содержимое файла, поэтому при их применении следует соблюдать осторожность.

Поскольку данные могут записываться не только на диск, но и в другие места (например, в именованные каналы или в память), важно уметь работать с файловым вводом-выводом в .NET, используя потоки в качестве средства для перемещения содержимого файлов. Об этом пойдет речь в следующей статье.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *