Считывание информации из файла одной строкой кода в JDK 7 или Java 8

java8_logo_white

Считать содержимое файла в Java непросто, необходимо использовать большое количество шаблонного кода, с которым мы уже сталкивались в предыдущем примере в статье считывание текстовых файлов. Нам приходилось делать «обертки» для многих вещей, например, помещать FileInputStream внутри BufferedReader, задавать циклы со странными условиями выхода и т.д. Начиная с JDK 7, ситуация значительно улучшилась. JDK предоставляет множество полезных классов, например Files и Paths, предназначенных для работы с файлами и путями к ним. В этой статье вы узнаете, как считать информацию из файла с помощью одной строки кода. Безусловно, ваш продакшн-код будет выглядеть иначе, особенно если вы считываете в память несколько гигабайт данных и при этом хотите учитывать кодировку. Если кодировка не выбрана, то используется кодировка платформы, заданная по умолчанию. Короче говоря, вам понадобится чуть больше кода, но для быстрого и грубого считывания файла этого способа будет достаточно. Кстати, если код будет содержать и обработку исключений, то он займет несколько строк. В готовом рабочем приложении вам нужно будет учитывать ситуацию, когда файл отсутствует, например, отображая пользователю сообщение об ошибке, отправляя метрики, сохраняя в журнал ошибку и т.д., но в любом случае в нем будет гораздо меньше шаблонного кода, чем в привычных для вас случаях.

Java 8 упростила жизнь разработчиков с помощью своего нового набора методов, которые используют преимущества API потоков (stream API). Кроме того, в класс Files было добавлено несколько новых методов, всегда использующих UTF-8, вместо произвольной кодировки платформы, например, Files.readAllLines(). Этот метод считывает все строки из файла. Байты из файла расшифровываются в символы с помощью кодировки UTF-8. Метод является эквивалентным методу Java 7 Files.readAllLines(path, StandardCharsets.UTF_8). Кстати,  ВСЕГДА явно указывайте кодировку символов при конвертировании массива байтов в строку String. Всегда явно указывайте кодировку, даже если ваш считываемый файл в текущий момент содержит только английский язык.

Считывание файла одной строкой кода в Java 7 и 8

Перед вами пример нашей программы на Java, демонстрирующей, как полностью считать файл всего одной строчкой кода. В нашем примере используется новый класс Files, появившийся в JDK 1.7, класс java.nio.file.Files содержит множество полезных методов для работы с файлами в Java, например, проверка, является ли файл скрытым, или доступен ли он только для чтения. Вы можете использовать команду Files.readAllBytes(Путь), чтобы полностью считать файл в память. Этот метод возвращает массив байтов, который может быть передан в конструктор String для создания из него строки String. Также метод позволяет гарантировать, что файл будет закрыт надлежащим образом после считывания всех байтов, или в случае возникновения ошибки ввода-вывода либо любого другого необработанного исключения, что означает, что вам не нужно закрывать файл в блоке finally, то есть, не нужно будет писать шаблонный код. Следует отметить, что данный метод не подходит для считывания больших файлов, поскольку, если в Heap будет недостаточно свободного места, у вас может закончиться память. Также вам следует явно указывать кодировку символов при конвертировании массива байтов в строку String во избежание неприятных сюрпризов или ошибки парсинга.

Если же вы хотите считать файл, как строку String, вы можете использовать другой метод, который называется readAllLines(Path path, Charset cs). Этот метод похож на предыдущий, т.е. он тоже закрывает файлы после считывания или в случае возникновения ошибки, но вместо массива байтов он возвращает строку, которая конвертируется из байтов с помощью указанного набора символов. Кроме того, в Java 8 была добавлена еще одна перегруженная версия этого метода, которая не требует параметра Charset (кодировка), и использует UTF-8 для конвертации байтов в String.

Приятности на этом не заканчиваются. Если вы хотите считать файл построчно, то можете воспользоваться методом Files.lines(), возвращающим поток со строками, считанными из файла, в которых байты конвертируются в символы с помощью кодировки UTF-8. Используя метод forEach(), вы можете вывести все строки файла в консоль с помощью всего одной строчки Java-кода, что продемонстрировано в третьем фрагменте кода.

 import java.io.IOException;
 import java.nio.charset.StandardCharsets;
 import java.nio.file.Files;
 import java.nio.file.Paths;
 import java.util.List;

 /**
  *  Simple Java program to read a text file into String in Java. 
  *  You can use this one liner code for quickly reading file and displaying  
  *  as String.
  *  @author Javin Paul
  */
 public class Java78FileReadingExample {
   public static void main(String args[]) throws IOException {

     System.out.println(new String(Files.readAllBytes(Paths.get("data_old.txt"))));
     System.out.println(new String(Files.readAllBytes(Paths.get("info.xml"))));

     // Java 8 Example - Uses UTF-8 character encoding
     List<String> lines = Files.readAllLines(Paths.get("data_old.txt"), StandardCharsets.UTF_8);
     StringBuilder sb = new StringBuilder(1024);
     for (String line : lines) {
       sb.append(line);
     }

     String fromFile = sb.toString();

     System.out.println("++++++++++++++++++++++++");
     System.out.println("String created by reading File in Java");
     System.out.println(fromFile);
     System.out.println("++++++++++++++++++++++++");
   }

Output: Java 7 and Java 8 has made reading file into String VERY EASY. 
Société Générale is a french bank Headquarter at Île-de-France, France 
++++++++++++++++++++++++
String created by reading File in Java Java 7 and Java 8 has made reading file into 
String VERY EASY. ++++++++++++++++++++++++
Reading File in Java

 

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

import static java.lang.System.out;
import static java.nio.file.Files.readAllBytes;
import static java.nio.file.Paths.get;
/**
 * Java Class to read a file in one line
 */
public class FileIntoString {
  public static void main(String[] args) throws Exception {
    out.println(new String(readAllBytes(get("data_old.txt"))));
  }
}

Если вы используете Java 8, вы также можете воспользоваться Stream API, дающим возможность писать более лаконичный и производительный код, что показано в следующем примере. Здесь метод lines() возвращает Stream of String (поток строк), который конвертируется из байтов, считанных из файла, в символы с помощью кодировки UTF-8. Это равносильно вызову метода Files.lines(path, StandardCharsets.UTF_8) в Java 7.

package test;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
/**
 * Java Program to demonstrate how to read File in Java 8 using Stream. * @author Javin Paul
 */
public class Java8FileReader {
  public static void main(String args[]) throws IOException {
    // В Java 8 вы можете использовать Streams и для дальнейшей оптимизации 
    Files.lines(Paths.get("manifest.mf"), StandardCharsets.UTF_8).forEach(System.out::println);
  }
}

Вот и все, что вам нужно знать, чтобы считать текст или бинарный файл с помощью одной строчки кода в Java 7. Как видите, новые инструменты File API в JDK 7 и Stream API в Java 8 значительно упростили задачу по считыванию данных из файлов в Java. Этот позволило полностью избавиться от шаблонного кода, что привело к гораздо более понятному и лаконичному коду. Кстати, если вы пишете продакшн-код, который выполняет считывание информации из файла, то не забудьте обратить внимание на следующие моменты:

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

Оригинал


Комментарии:

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

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

Можно использовать следующие HTML-теги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>