- Reading and writing files in Java (Input/Output) — Tutorial
- 1.2. Reading a file in Java
- 1.3. Reading and filtering line by line
- 1.4. Writing a file in Java
- 1.5. List all files and sub-directories using Files.list()
- 1.6. How to identify the current directory
- 2. Exercise: Reading and writing files
- 3. Example: Recursively listing all files of a diretory
- 4. Example: Deleting a directory with all subdirectories and files
- 5. Reading resources out of your project / jar
- Java file in project directory
- Read a File from Resources Folder in Java
- Overview
- Using Plain Java – getResourceAsStream()
- Using FileReader
- Using Files.newBufferedReader()
- Using Files.lines()
- Using DataInputStream
- Using FileChannel
- Summary
Reading and writing files in Java (Input/Output) — Tutorial
Java provides the java.nio.file API to read and write files. The InputStream class is the superclass of all classes representing an input stream of bytes.
1.2. Reading a file in Java
To read a text file you can use the Files.readAllBytes method. The usage of this method is demonstrated in the following listing.
import java.io.IOException; import java.nio.file.Files; import java.nio.file.Paths; // somewhere in your code String content = Files.readString(Path.of("resources", "work", "input.xml"));
To read a text file line by line into a List of type String structure you can use the Files.readAllLines method.
ListString> lines = Files.readAllLines(Paths.get(fileName));
Files.readAllLines uses UTF-8 character encoding. It also ensures that file is closed after all bytes are read or in case an exception occurred.
1.3. Reading and filtering line by line
The Files.lines method allows read a file line by line, offering a stream. This stream can be filtered and mapped. Files.lines does not close the file once its content is read, therefore it should be wrapped inside a try-with-resource statement.
In the following example unnecessary whitespace at the end of each line is removed and empty lines are filterer.
//read all lines and remove whitespace (trim) //filter empty lines //and print result to System.out Files.lines(new File("input.txt").toPath()) .map(s -> s.trim()) .filter(s -> !s.isEmpty()) .forEach(System.out::println);
The next example demonstrates how to filter out lines based on a certain regular expression.
Files.lines(new File("input.txt").toPath()) .map(s -> s.trim()) .filter(s -> !s.matches("yourregularexpression")) .forEach(System.out::println);
The next example extracts a line starting with «Bundle-Version:» from a file called MANIFEST.MF located in the META-INF folder. It removes the prefix and removes all leading and trailing whitespace.
package com.vogella.eclipse.ide.first; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Paths; import java.util.Optional; import java.util.stream.Stream; public class ReadMANIFESTFile public static void main(String[] args) throws IOException String versionString = readStreamOfLinesUsingFiles(); System.out.println(versionString); > private static String readStreamOfLinesUsingFiles() throws IOException StreamString> lines = Files.lines(Paths.get("META-INF", "MANIFEST.MF")); OptionalString> versionString = lines.filter(s -> s.contains("Bundle-Version:")).map(e-> e.substring(15).trim()).findFirst(); lines.close(); if (versionString.isPresent()) return versionString.get(); > return ""; > >
1.4. Writing a file in Java
To write a file you can use the following method:
Files.write(stateFile.toPath(), content.getBytes(StandardCharsets.UTF_8), StandardOpenOption.CREATE);
1.5. List all files and sub-directories using Files.list()
You can access files relative to the current execution directory of your Java program. To access the current directory in which your Java program is running, you can use the following statement.
// writes all files of the current directory Files.list(Paths.get(".")).forEach(System.out::println);
1.6. How to identify the current directory
String currentDir = System.getProperty("user.dir");
2. Exercise: Reading and writing files
Create a new Java project called com.vogella.java.files. Create the following FilesUtil.java class.
package com.vogella.java.files; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Paths; import java.nio.file.StandardOpenOption; import java.util.List; public class FilesUtil public static String readTextFile(String fileName) throws IOException String content = new String(Files.readAllBytes(Paths.get(fileName))); return content; > public static ListString> readTextFileByLines(String fileName) throws IOException ListString> lines = Files.readAllLines(Paths.get(fileName)); return lines; > public static void writeToTextFile(String fileName, String content) throws IOException Files.write(Paths.get(fileName), content.getBytes(), StandardOpenOption.CREATE); > >
To test these methods, create a text file called file.txt with some content in your project folder. Create the following Main class and run it.
package com.vogella.java.files; import java.io.IOException; import java.nio.file.Path; import java.nio.file.Paths; public class Main public static void main(String[] args) throws IOException String input = FilesUtil.readTextFile("file.txt"); System.out.println(input); FilesUtil.writeToTextFile("copy.txt", input); System.out.println(FilesUtil.readTextFile("copy.txt")); FilesUtil.readTextFileByLines("file.txt"); Path path = Paths.get("file.txt"); > >
3. Example: Recursively listing all files of a diretory
Java 8 provides a nice stream to process all files in a tree.
Files.walk(Paths.get(path)) .filter(Files::isRegularFile) .forEach(System.out::println);
4. Example: Deleting a directory with all subdirectories and files
To delete a directory and all its content.
String stringPath=". yourPath. "; Path path = new File(stringPath).toPath(); Files.walk(path) .sorted(Comparator.reverseOrder()) .map(Path::toFile) .forEach(File::delete);
5. Reading resources out of your project / jar
You can read resources from your project or your jar file via the .getClass().getResourceAsStream() method chain from any object.
Java file in project directory
Path testFile = Paths.get(«C:\\Users\\jleom\\Desktop\\java\\javarush task\\test.txt»); Path testFile2 = Paths.get(«C:\\Users\\jleom\\Desktop»); System.out.println(testFile.relativize(testFile2));
Класс Path и класс Paths предназначены для работы с файловой системой в Java, однако они предоставляют разные функции и методы. Path — это интерфейс, который определяет методы для работы с путями к файлам и каталогам в файловой системе. Он предоставляет ряд методов для работы с путями, таких как resolve(), relativize(), getParent(), getFileName(), toAbsolutePath() и другие. Paths — это утилитный класс, который предоставляет статические методы для создания экземпляров класса Path. Он не имеет методов для работы с путями напрямую, но предоставляет методы для создания экземпляров Path из строковых значений или URI. Еще методы по классу Paths: getFileSystem(): возвращает объект FileSystem, представляющий файловую систему, которой принадлежит данный путь. getDefault(): возвращает объект FileSystem, представляющий файловую систему по умолчанию. getTempDirectory(): возвращает объект типа Path, представляющий временный каталог. getHomeDirectory(): возвращает объект типа Path, представляющий домашний каталог пользователя. exists(Path path, LinkOption. options): проверяет, существует ли файл или каталог, представленный указанным путем. Класс Paths удобен для работы с файловой системой, так как он предоставляет простой и удобный API для работы с путями.
Надо добавить в статью, Paths.get был в 8 Java. Потом появился Path.of. Если у вас не работает Path.of (версия Java не позволяет), только тогда нужен Paths.get
Read a File from Resources Folder in Java
This tutorial illustrates How to read a file from Classpath or Resources Folder in Java using File IO, NIO, and FileChannel.
Overview
All Maven and Gradle projects follow Maven’s standard directory structure (link), which helps segregate different types of source files in dedicated directories. Application-level configurations (like Properties and YAML) and other files reside in the resources directory.
- src/main/resources – A place to keep Application level resources and files.
- src/test/resources – A place to keep resources and files for the test purpose.
Java provides several ways to read the files from the resources directory. The following tutorial covers examples of reading files from ‘src/main/resources‘ or ‘src/test/resources‘ directory.
Using Plain Java – getResourceAsStream()
Java Class class provides the getResourceAsStream() method that can open an InputStream to a file in the classpath.
To read a file from the ‘src/main/resources‘ we need to provide a file path relative to this directly. When we invoke getResourceAsStream() in a unit test, it reads the file from ‘src/test/resources‘ directory.
InputStream inputStream = this.getClass().getResourceAsStream("/file.txt");
Code language: Java (java)
We can now use the InputStream instance to read the file’s contents.
try ( InputStream is = this.getClass().getResourceAsStream("/file.txt"); InputStreamReader isr = new InputStreamReader(is); BufferedReader br = new BufferedReader(isr); Stream lines = br.lines(); ) Code language: Java (java)
Firstly, we use the Class.getResourceAsStream() method to retrieve an InputStream to the intended file. Then we create an InputStreamReader instance to build a BufferedReader instance. The BufferedReader‘s lines() method provides a Java Stream of the lines from the file.
The lines() method of the BufferedReader is lazy. This means it reads lines if we consume the stream.
Note that we are using try-with-resources that automatically helps us close various File IO resources and streams.
Alternatively, we can use getResourceAsStream on the class loader.
InputStream inputStream = this.getClass() .getClassLoader() .getResourceAsStream("file.txt");
Code language: Java (java)
The difference between the two is that using getResourceAsStream() on the Class instance is relative to the resources folder. Thus, we added a slash (/) to the path. On the other hand, getResourceAsStream() on the class loader instance takes an absolute path, which is why we have not added the slash (/).
Using FileReader
We can create a FileReader instance by providing the file’s path relative to the project root. We can then wrap the FileReader into a BufferedReader instance and use the BufferedReader to read the file in a Stream of lines.
Example of using the FileReader to read a file from the resources directory
try ( FileReader fr = new FileReader("src/main/resources/file.txt"); BufferedReader br = new BufferedReader(fr); Stream lines = br.lines(); ) Code language: Java (java)
Using Files.newBufferedReader()
Java NIO’s Files class provides a static method, newBufferedReader(), that we can use to build a BufferedReader instance. To do so, we must give the file’s path relative to the project root.
Example of using the newBufferedReader() method from Java NIO Files class to read a file from the resources directory.
try ( BufferedReader br = Files.newBufferedReader( Paths.get("src/main/resources/file.txt")); Stream lines = br.lines(); ) Code language: Java (java)
Using Files.lines()
Alternatively, the more straightforward way is to use the Java NIO Files class’s lines() method. The lines() method accepts the file’s path relative to the project root directory. It returns a Java Stream of the lines from the file.
Example of using the lines() method of Java NIO Files to read a file from the “src/main/resources” or “src/test/resources” directory.
try ( Stream lines = Files.lines(path, StandardCharsets.UTF_8) ) Code language: Java (java)
Using DataInputStream
We can also combine the Java Class’s getResourceAsStream() method with an DataInputStream instance to read a file from the resources directory or classpath.
Example of using the DataInputStream to read a file from the resources folder.
try ( InputStream is = this.getClass().getResourceAsStream("/file.txt"); DataInputStream dis = new DataInputStream(is); ) < int numBytesRead; if ((numBytesRead = dis.available()) > 0) < byte[] bucket = new byte[numBytesRead]; dis.read(bucket); System.out.println(new String(bucket)); > >
Code language: Java (java)
Firstly, we used the getResourceAsStream() method to create an InputStream to the file from resources directory. Next, we wrapped the InputStream instance into a DataInputStream instance. The DataInputStream is useful for reading primitive java data types from a file.
Using FileChannel
Using FileChannel to read a file from the resources diretory is fastest of all the ways, especially when the file is large.
Example of using the FileChannel to read a file from “src/main/resources” or “src/test/resources” directory.
Path path = Path.of(this.getClass().getResource("/file.txt").toURI()); try ( RandomAccessFile raf = new RandomAccessFile(path.toFile(), "r"); FileChannel fc = raf.getChannel(); ) < int bucketSize = 1024; ByteBuffer byteBuffer = ByteBuffer.allocate(bucketSize); fc.read(byteBuffer); byteBuffer.flip(); System.out.println(new String(byteBuffer.array())); >
Code language: Java (java)
To obtain a FileChannel mapped to our file, we first create a RandomAccessFile instance. We can then use the FileChannel instance to read the file chunk by chunk.
Summary
In this detailed tutorial, we have learned different ways of reading a file from the resources directory (“src/main/resources” or “src/test/resources” folders) or classpath. We went through the examples of reading a files using the plain Java, Java NIO, and FileChannel.