Reading a File in Java

Different ways to read a text file into a String in Java.

BufferedReader

java.io.FileReader can be used to read character files. We often see it used together with BufferedReader.
java.io.BufferedReader is the class we can use to read text from a character-input stream. It bufferes characters for efficient reading of characters, arrays and lines.

1
2
3
4
5
6
7
8
9
10
11
12
13
public static String readFile(String path) {
File file = new File(path);
StringBuilder strBuilder = new StringBuilder();
try (BufferedReader br = new BufferedReader(new FileReader(file))) {
String line;
while ((line = br.readLine()) != null) {
strBuilder.append(line).append("\n");
}
} catch (IOException e) {
e.printStackTrace();
}
return strBuilder.toString();
}

Alternatively, you can use Files.newBufferedReader method to quickly create a BufferedReader.

1
2
3
4
5
6
7
8
9
10
11
12
public static String readFile(String path) {
StringBuilder strBuilder = new StringBuilder();
try (BufferedReader br = Files.newBufferedReader(Path.of(path))) {
String line;
while ((line = br.readLine()) != null) {
strBuilder.append(line).append("\n");
}
} catch (IOException e) {
e.printStackTrace();
}
return strBuilder.toString();
}

Files.readAllBytes

java.nio.file.Files class provide static methods to operate on files, directories, or other types of files. We can use Files.readAllBytes to read the file. This is simplier than BufferedReader.

1
2
3
4
5
6
7
8
public static String readFile(String path) {
try {
return new String(Files.readAllBytes(Paths.get(path)), StandardCharsets.UTF_8);
} catch (IOException e) {
e.printStackTrace();
}
return null;
}

readAllBytes is not intended for reading in large files.

Files.readString

java.nio.file.Files has readString(Path) method to read all content from a file into a string.

1
2
3
4
5
6
7
8
public static String readFile(String path) {
try {
return Files.readString(Paths.get(path), StandardCharsets.UTF_8);
} catch (IOException e) {
e.printStackTrace();
}
return null;
}

FIles.lines

java.nio.file.Files has lines(Path) method to read all lines from a file as a Stream.

1
2
3
4
5
6
7
8
9
public static String readFile(String path) {
try {
return Files.lines(Paths.get(path), StandardCharsets.UTF_8)
.collect(Collectors.joining(System.lineSeparator()));
} catch (IOException e) {
e.printStackTrace();
}
return null;
}

FileUtils

To use FileUtils or IOUtils to read file, we need to add commons-io as maven dependency.

1
2
3
4
5
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.8.0</version>
</dependency>

FileUtils.readFileToString

We can use FileUtils.readFileToString method to read the contents of a file into a string using the specified charset.

1
2
3
4
5
6
7
8
9
10
public static String readFile(String path) {
File file = new File(path);
String content = null;
try {
content = FileUtils.readFileToString(file, StandardCharsets.UTF_8);
}catch(IOException e) {
e.printStackTrace();
}
return content;
}

FileUtils.readLines

We can also use FileUtils.readLines method to read lines and then concatenate all the lines together.

1
2
3
4
5
6
7
8
9
10
11
public static String readFile(String path) {
File file = new File(path);
String content = null;
try {
List<String> lines = FileUtils.readLines(file, StandardCharsets.UTF_8);
content = lines.stream().collect(Collectors.joining("\n"));
}catch(IOException e) {
e.printStackTrace();
}
return content;
}

IOUtils

IOUtils.toString

This is similar to FileUtils.readFileToString except IOUtils takes an InputStream class. When we have a InputStream, It is more convenient to use IOUtils instead.

1
2
3
4
5
6
7
8
9
10
public static String readFile(String path) {
File file = new File(path);
String content = null;
try (FileInputStream inputStream = new FileInputStream(file)){
content = IOUtils.toString(inputStream, StandardCharsets.UTF_8);
}catch(IOException e) {
e.printStackTrace();
}
return content;
}

IOUtils.readLines

This is similar to FileUtils.readLines except IOUtils takes an InputStream class.

1
2
3
4
5
6
7
8
9
10
11
public static String readFile(String path) {
File file = new File(path);
String content = null;
try (FileInputStream inputStream = new FileInputStream(file)){
List<String> lines = IOUtils.readLines(inputStream, StandardCharsets.UTF_8);
content = lines.stream().collect(Collectors.joining("\n"));
}catch(IOException e) {
e.printStackTrace();
}
return content;
}

Read File from Classpath

Both Class and ClassLoader provides methods to get resource from classpath.

Class.getResource can take a “relative” resource name, which is treated relative to the class’s package. Alternatively you can specify an “absolute” resource name by using a leading slash. Classloader resource paths are always deemed to be absolute.

We can get the classloader of a class and then use getResourceAsStream method to get resource as InputStream. After we get InputStream, we can use InputStream.readAllBytes method to convert InputStream to bytes and create String from the bytes.

Example to read file in src/main/resources/com/xinghua24/file.txt assuming the class is in com.xinghua24 package.

1
2
3
4
5
6
7
8
9
public String readFileFromClasspath() {
InputStream inputStream = getClass().getClassLoader().getResourceAsStream("com/xinghua24/file.txt");
try {
return new String(inputStream.readAllBytes(), StandardCharsets.UTF_8);
} catch (IOException e) {
e.printStackTrace();
}
return null;
}

Example to read file in src/main/resources/com/xinghua24/file.txt assuming the class is in com.xinghua24 package using getClass().getResourceAsStream() mehtod.

1
2
3
4
5
6
7
8
9
public String readFileFromClasspath() {
InputStream inputStream = getClass().getResourceAsStream("file.txt");
try {
return new String(inputStream.readAllBytes(), StandardCharsets.UTF_8);
} catch (IOException e) {
e.printStackTrace();
}
return null;
}

The difference between getClass().getResource() and getClass().getClassLoader().getResource():

  • For ClassLoader, all paths are “absolute” already. There is no context from which they could be relative. Therefore you don’t need a leading slash.
  • For Class, all paths are “relative” by default. the path is relative to the package of the class unless you include aleading slash(/). If path begines with a slash(/), the path becomes absolute.

ClassPathResource

If you are using Spring Framework, you can use Spring’s ClassPathResource to get the resource from classpath. through the Resource interface you can access the resource as InputStream, URL, URI or File.

1
2
3
4
5
6
7
8
9
public String readFileFromClasspath() {
ClassPathResource fileResource = new ClassPathResource("com/xinghua24/file.txt");
try {
return new String(fileResource.getInputStream().readAllBytes());
} catch (IOException e) {
e.printStackTrace();
}
return null;
}

Reference