Java: чтение файла в строку

Введение В этом руководстве мы будем считывать файл в строку в Java. Есть несколько способов чтения текстового содержимого файла. Вот список всех классов и методов, которые мы рассмотрим: * Files.lines () * Files.readString () * Files.readAllBytes () * FileReader * BufferedReader * Scanner Files.lines () Класс Files содержит статические методы для работы с файлами и каталогами. Полезный метод - lines (), который возвращает поток строк: Stream<String> . Из этого потока,

Вступление

В этом руководстве мы будем читать файл в виде строки в Java. Есть несколько способов чтения текстового содержимого файла.

Вот список всех классов и методов, которые мы рассмотрим:

Files.lines ()

Класс Files содержит статические методы для работы с файлами и каталогами. Полезный метод - lines() который возвращает поток строк: Stream<String> . Из этого потока можно получить строки, содержащиеся в файле.

Метод принимает Path к файлу, который мы хотели бы прочитать, с необязательной Charset . Мы будем использовать try-with-resources для автоматизации очистки и закрытия:

 Path path = Paths.get("input.txt"); 
 
 try (Stream<String> stream = Files.lines(path, StandardCharsets.UTF_8)) { 
 stream.forEach(System.out::println); 
 } catch (IOException ex) { 
 // Handle exception 
 } 

Поскольку метод возвращает Stream , мы используем его forEach() для перебора строк со ссылкой на метод для краткости.

Вместо печати каждой линии, StringBuilder может быть использован для добавления строк:

 Path path = Paths.get("input.txt"); 
 
 StringBuilder sb = new StringBuilder(); 
 
 try (Stream<String> stream = Files.lines(path)) { 
 stream.forEach(s -> sb.append(s).append("\n")); 
 
 } catch (IOException ex) { 
 // Handle exception 
 } 
 
 String contents = sb.toString(); 

С помощью StringBuilder весь файл может быть представлен в одной String ( contents выше переменная содержимого). Перед выполнением таких итераций важно учитывать длину входного файла.

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

Files.readString ()

Начиная с Java 11, Files познакомил нас с readString() , который принимает Path к файлу, а также Charset .

В отличие от Files.lines() , он возвращает String напрямую, а не объект Stream

 Path path = Paths.get("input.txt"); 
 
 String contents = null; 
 try { 
 contents = Files.readString(path, StandardCharsets.ISO_8859_1); 
 } catch (IOException ex) { 
 // Handle exception 
 } 

Files.readAllBytes ()

Более низкоуровневый подход к чтению - это Files.readAllBytes() , который возвращает byte[] . Разработчик должен использовать эти байты

  • преобразовать их в строку, обработать как есть и т. Д.

Этот метод также принимает Path к файлу, который мы хотим прочитать:

 Path path = Paths.get("input.txt"); 
 
 byte[] bytes = null; 
 try { 
 bytes = Files.readAllBytes(path); 
 } catch (IOException ex) { 
 // Handle exception 
 } 

Теперь bytes содержит всю информацию из файла input.txt Самый простой способ преобразовать его в String - поместить их в конструктор с необязательным Charset :

 String str = new String(bytes, StandardCharsets.UTF_8); 

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

Сканер

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

Поскольку мы работаем со строками, мы хотели бы использовать методы, возвращающие строки. Scanner имеет next() и nextLine() именно для этого. Оба метода возвращают объекты типа String . Первый используется для чтения произвольных строк, тогда как второй анализирует и возвращает целые строки.

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

Scanner принимает множество объектов - Path , InputStream , File и т. Д. Мы будем использовать File :

 File file = new File("input.txt"); 
 Scanner sc = new Scanner(file); 
 
 while(sc.hasNext()) { 
 System.out.println(sc.next()); 
 } 

Мы используем while цикл до тех пор , как sc имеет больше элементов. Если бы мы не проверили с помощью hasNext() , sc выдаст NoSuchElementexception если мы попытаемся получить доступ к элементу после последнего.

Идея использования hasNext() и next() исходит из Iterator , поскольку Scanner внутренне его реализует.

FileReader

FileReader используется для чтения файлов. Он предлагает read() и read(char[]) , которые возвращают один символ и несколько символов соответственно. Кроме того, он принимает в конструктор File или String .

FileReader.read (char [])

Откроем файл с помощью FileReader и прочитаем его содержимое:

 FileReader in = new FileReader("input.txt"); 
 
 char[] chars = new char[256]; 
 int n = in.read(chars, 0, chars.length); 
 
 String contents = new String(chars); 

Метод read() принимает последовательность символов (в которой мы сохраняем прочитанные символы), начальную и конечную точки того, что мы хотим прочитать. В частности, мы решили читать не более 256 символов. Если в input.txt больше, мы прочитаем только 256 символов. Если его меньше, возвращаются читаемые символы.

Возвращаемое значение, хранящееся внутри целого числа n может использоваться для проверки того, сколько символов фактически прочитал метод. Если достигнут конец потока, метод возвращает -1 .

Поскольку метод заполняет char[] , мы можем преобразовать его в String . Аналогичный результат можно получить, используя String.valueOf(char[]) .

FileReader.read ()

Метод read() без char[] читает по одному символу за раз. Нам нужно перебрать содержимое и прочитать каждый символ самостоятельно:

 FileReader in = new FileReader("input.txt"); 
 
 StringBuilder sb = new StringBuilder(); 
 
 while(in.read() != -1) { 
 sb.append(in.read()); 
 } 
 
 String contents = sb.toString(); 
 in.close(); 

Здесь мы проверяем, не является ли прочитанный символ -1 , что указывает на то, что символов для чтения не осталось. Если нет, мы append() его к StringBuilder и, наконец, преобразуем его в String .

Примечание. И read() и read(char[]) читают байты, преобразуют их в символы и возвращают их один за другим . Это неэффективно и по возможности должно выполняться с буферизацией .

BufferedReader

BufferedReader - это объект, предназначенный для чтения текста из потока ввода символов. Он буферизован, что означает, что он использует внутренний буфер для временного хранения. Как мы видели в предыдущем разделе, «обычные» Reader иногда могут быть неэффективными.

Рекомендуется обернуть любой потенциально дорогостоящий Reader в BufferedReader для повышения производительности, поскольку символы буферизации позволяют более эффективно читать вводимый текст.

Создадим экземпляр BufferedReader :

 BufferedReader in = new BufferedReader(new FileReader("input.txt")); 

На данный момент у нас есть буферный объект чтения, готовый читать содержимое из input.txt . В этом примере мы будем читать файл построчно, хотя BufferedReader поддерживает чтение отдельных символов по отдельности, а также нескольких символов в массив.

Давайте воспользуемся этим BufferedReader для чтения файла и сохранения его содержимого построчно в строку:

 StringBuilder sb = new StringBuilder(); 
 
 while(in.readLine != null) { 
 sb.append(in.readLine()).append("\n"); 
 } 
 
 String contents = sb.toString(); 
 in.close(); 

И снова мы используем StringBuilder для сбора всех строк. Чтобы отделить каждую строку, мы добавляем между ними \n Наконец, закрываем поток.

Заключение

В этой статье мы рассмотрели некоторые распространенные техники чтения файлов в строки в Java. Есть много вариантов, но большинство из них имеют схожий основной принцип: указать путь к файлу, прочитать содержимое в структуре данных (например, char[] или String); затем выполните некоторую заключительную обработку, чтобы соответствующим образом собрать все содержимое файла.

Мы рассмотрели метод File.lines() метод Files.readString() метод Files.readAllBytes() , а также классы Scanner , FileReader и BufferedReader

Licensed under CC BY-NC-SA 4.0
comments powered by Disqus