Как читать файл в Java

Как читать файл в Java

1. Вступление

В этой статье мы увидим, как мы можем прочитать файл из пути к классам, URL или из файла JAR, используя стандартные классы Java.

Дальнейшее чтение:

Java - Создать файл

Как создать файл в Java, используя JDK 6, JDK 7 с NIO или Commons IO.

Read more

Java - запись в файл

Множество способов записи данных в файл с использованием Java.

Read more

2. Настроить

Мы будем использовать набор тестовых примеров, используя только базовые классы Java, а в тестах мы будем использовать утверждения с использованием сопоставителейHamcrest.

Тесты будут использовать общий методreadFromInputStream , который преобразуетInputStream toString для упрощения утверждения результатов:

private String readFromInputStream(InputStream inputStream)
  throws IOException {
    StringBuilder resultStringBuilder = new StringBuilder();
    try (BufferedReader br
      = new BufferedReader(new InputStreamReader(inputStream))) {
        String line;
        while ((line = br.readLine()) != null) {
            resultStringBuilder.append(line).append("\n");
        }
    }
  return resultStringBuilder.toString();
}

Обратите внимание, что есть и другие способы достижения того же результата. Вы можете проконсультироваться сthis article по поводу некоторых альтернатив.

3. Прочитать файл из пути к классам

В этом разделе объясняется, как прочитать файл, который доступен на пути к классам. Мы прочитаем «fileTest.txt» подsrc/main/resources:

@Test
public void givenFileNameAsAbsolutePath_whenUsingClasspath_thenFileData() {
    String expectedData = "Hello World from fileTest.txt!!!";

    Class clazz = FileOperationsTest.class;
    InputStream inputStream = clazz.getResourceAsStream("/fileTest.txt");
    String data = readFromInputStream(inputStream);

    Assert.assertThat(data, containsString(expectedData));
}

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

Тот же метод доступен и для синстанцииClassLoader :

ClassLoader classLoader = getClass().getClassLoader();
InputStream inputStream = classLoader.getResourceAsStream("fileTest.txt");
String data = readFromInputStream(inputStream);

Мы получаемclassLoader для текущего класса, используяgetClass().getClassLoader().

Основное отличие состоит в том, что при использовании синстанцииgetResourceAsStream on aClassLoader путь рассматривается как абсолютный, начиная с корня пути к классам.

При использовании противClass instance, путь может быть относительно пакета или абсолютным путем, на который указывает начальная косая черта.

Of course, note that in practice, open streams should always be closed, напримерInputStream в нашем примере:

InputStream inputStream = null;
try {
    File file = new File(classLoader.getResource("fileTest.txt").getFile());
    inputStream = new FileInputStream(file);

    //...
}
finally {
    if (inputStream != null) {
        try {
            inputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

4. Прочитать файл с помощью JDK7

В JDK7 пакет NIO был значительно обновлен. Давайте посмотрим на пример с использованием классаFiles и методаreadAllBytes. МетодreadAllBytes принимает классPath. Path, что можно рассматривать как обновлениеjava.io.File с некоторыми дополнительными операциями:

@Test
public void givenFilePath_whenUsingFilesReadAllBytes_thenFileData() {
   String expectedData = "Hello World from fileTest.txt!!!";

   Path path = Paths.get(getClass().getClassLoader()
     .getResource("fileTest.txt").toURI());
   byte[] fileBytes = Files.readAllBytes(path);
   String data = new String(fileBytes);

   Assert.assertEquals(expectedData, data.trim());
}

Этот метод также предлагает удобный способ чтения содержимого файла вString.

5. Прочитать файл с помощью JDK8

JDK8 предлагает методlines() внутри классаFiles. Он возвращаетStream элементов String.

Давайте рассмотрим пример того, как считывать данные в байты и декодировать их с помощью кодировки UTF-8:

@Test
public void givenFilePath_whenUsingFilesLines_thenFileData() {
    String expectedData = "Hello World from fileTest.txt!!!";

    Path path = Paths.get(getClass().getClassLoader()
      .getResource("fileTest.txt").toURI());

    Stream lines = Files.lines(path);
    String data = lines.collect(Collectors.joining("\n"));
    lines.close();

    Assert.assertEquals(expectedData, data.trim());
}

Используя Stream с каналами ввода-вывода, такими как файловые операции, нам нужно явно закрыть поток, используя методclose().

Как мы видим, APIFiles предлагает еще один простой способ прочитать содержимое файла вString.

6. Прочитать файл с помощью FileUtils

Другой распространенный вариант - использование классаFileUtils пакетаcommons. Нам нужно будет добавить следующую зависимость:


    commons-io
    commons-io
    2.5

Обязательно проверьте последнюю версию зависимостиhere.

Код чтения файла может выглядеть так:

@Test
public void givenFileName_whenUsingFileUtils_thenFileData() {
    String expectedData = "Hello World from fileTest.txt!!!";

    ClassLoader classLoader = getClass().getClassLoader();
    File file = new File(classLoader.getResource("fileTest.txt").getFile());
    String data = FileUtils.readFileToString(file, "UTF-8");

    Assert.assertEquals(expectedData, data.trim());
}

Здесь мы передаем объектFile методуreadFileToString() классаFileUtils. Этот служебный класс позволяет загружать содержимое без необходимости писать какой-либо шаблонный код для создания экземпляраInputStream и чтения данных.

7. Прочитать файл с помощьюIOUtils

Другой распространенный вариант - использование классаIOUtils пакетаcommons. Вам нужно будет добавить такую ​​же зависимостьcommon-io, как упоминалось в предыдущем примереFileUtils.

Давайте посмотрим на пример использования:

@Test
public void givenFileName_whenUsingIOUtils_thenFileData() {
    String expectedData = "This is a content of the file";

    FileInputStream fis = new FileInputStream("src/test/resources/fileToRead.txt");
    String data = IOUtils.toString(fis, "UTF-8");

    assertEquals(expectedData, data.trim());
}

Здесь мы передаем объектFileInputStream методуtoString() классаIOUtils. Этот служебный класс позволяет загружать содержимое без необходимости писать какой-либо шаблонный код для создания экземпляраInputStream и чтения данных.

8. Читать содержимое с URL

Для чтения содержимого с URL-адреса мы будем использовать URL-адрес «/» в нашем примере как:

@Test
public void givenURLName_whenUsingURL_thenFileData() {
    String expectedData = "example";

    URL urlObject = new URL("/");
    URLConnection urlConnection = urlObject.openConnection();
    InputStream inputStream = urlConnection.getInputStream();
    String data = readFromInputStream(inputStream);

    Assert.assertThat(data, containsString(expectedData));
}

Есть также альтернативные способы подключения к URL. Здесь мы использовали классыURL иURLConnection, доступные в стандартном SDK.

9. Прочитать файл из JAR

Чтобы прочитать файл, который находится внутри файла JAR, нам понадобится JAR с файлом внутри него. В нашем примере мы прочитаем «LICENSE.txt» из файла «hamcrest-library-1.3.jar»:

@Test
public void givenFileName_whenUsingJarFile_thenFileData() {
    String expectedData = "BSD License";

    Class clazz = Matchers.class;
    InputStream inputStream = clazz.getResourceAsStream("/LICENSE.txt");
    String data = readFromInputStream(inputStream);

    Assert.assertThat(data, containsString(expectedData));
}

Здесь мы хотим загрузитьLICENSE.txt, который находится в библиотеке Hamcrest, поэтому мы будем использовать классMatcher’s, который помогает получить ресурс. Этот же файл можно загрузить с помощью загрузчика классов.

10. Заключение

В этом руководстве мы увидели, как читать файл из разных мест, таких как путь к классам, URL или файлы jar.

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

Вы можете найти исходный код в следующихGitHub repo.