Wednesday, July 27, 2022

How to read File into String in Java 7, 8 with Example

Many times you want to read contents of a file into String, but, unfortunately, it was not a trivial job in Java, at least not until JDK 1.7. In Java 8, you can read a file into String in just one line of code. Prior to the release of new File IO API, you have to write a lot of boilerplate code e.g. open an input stream, convert that input stream into a Reader, and then wrap that into a BufferedReader and so on. Of course, JDK 1.5's Scanner class did provide some breathing space but it was still not as simple as it should be, like in Python or Ruby. By using Java 7 new File API and Java 8's new features like lambda expression and Stream API, Java is now close to Python or other utility languages, when it comes to reading the file into String.

In this article, you will learn a couple of ways to read a file into String in just a couple of lines, mostly one line. Though, whenever you convert binary data into text data, you must remember to use correct character encoding. An incorrect choice of character encoding may result in totally different or slightly different content than the original file.

Another advantage of using new features of JDK 8 such as lambda expression and streams are that they are lazy, which means better performance. It's particularly beneficial if you only need a portion of file e.g. all the lines which contain word "Error" or "Exception" or "Order" etc.



Reading File to String in Java

In order to understand the beauty of Java 7 way of reading the file into String, first, let's see how we used to do it in Java 1.5 and 6.

InputStream is = new FileInputStream("manifest.mf");
BufferedReader buf = new BufferedReader(new InputStreamReader(is));
        
String line = buf.readLine();
StringBuilder sb = new StringBuilder();
        
while(line != null){
   sb.append(line).append("\n");
   line = buf.readLine();
}
        
String fileAsString = sb.toString();
System.out.println("Contents : " + fileAsString);

You can see that it's not easy, you need to write a lot of unnecessary boilerplate code. This is even when we are just writing for the demo, forget about production quality code when you have to handle exceptions properly. 

Worth noting is that in this example we are using platform's default character encoding, which is fine because manifest.mf has not contained any character other than ASCII, but it's not a safe way if you don't know the encoding, by default use "UTF-8". Now let's see how you can read a file as String in JDK 1.7

String contents = new String(Files.readAllBytes(Paths.get("manifest.mf")));
System.out.println("Contents (Java 7) : " + contents);

You can see there is no more wrapping around different class, no more loop, no more handling of the special condition, just a method call to read the whole file into a byte array and then create String from it. Just like our previous example, this is also using platform's default character encoding.

You can also see Core Java for Impatient book by Cay S. Horstmann, one of the better books to learn subtle details of Java and it covers Java SE 8 as well.

Let's see how can we provide a custom character encoding of our choice:

String fileString = new String(Files.readAllBytes(Paths.get("manifest.mf")),
  StandardCharsets.UTF_8);
System.out.println("Contents (Java 7 with character encoding ) : " 
  + fileString);


Now does it get any simpler with Java 8 Streams and lambda expression, well it does, as we have seen in my earlier article about how to read file in Java 8, its same as Java 7, how can you go less than one line, but yes you can use Stream and its lazy evaluation for your benefit :

Files.lines(Paths.get("manifest.mf"), StandardCharsets.UTF_8)
      .forEach(System.out::println);

You should get familiar with new File API, it's really helpful to do efficient file IO in Java, as shown below:

How to read file into String in Java 8



Program to Read Contents of a File in Java 8

Here is the complete code sample of how to read the file as String in Java 5, 6, 7 and 8. You can see that Java 7 has really made it a trivial task.

package test;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;


/**
 * Java Program to demonstrate different ways to loop over collection in 
 * pre Java 8 and Java 8 world using Stream's forEach method.
 * @author Javin Paul
 */
public class FileToStringJava8 {

    public static void main(String args[]) throws IOException {

        // How to read file into String before Java 7
        InputStream is = new FileInputStream("manifest.mf");
        BufferedReader buf = new BufferedReader(new InputStreamReader(is));
        
        String line = buf.readLine();
        StringBuilder sb = new StringBuilder();
        
        while(line != null){
            sb.append(line).append("\n");
            line = buf.readLine();
        }
        
        String fileAsString = sb.toString();
        System.out.println("Contents (before Java 7) : " + fileAsString);
        
        
        // Reading file into Stirng in one line in JDK 7
        String contents 
              = new String(Files.readAllBytes(Paths.get("manifest.mf")));
        System.out.println("Contents (Java 7) : " + contents);
        
        
        
        // Reading file into String using proper character encoding
        String fileString 
        = new String(Files.readAllBytes(Paths.get("manifest.mf")), 
                    StandardCharsets.UTF_8);
        System.out.println("Contents (Java 7 with character encoding ) : " 
             + fileString);
        

        // It's even easier in Java 8
        Files.lines(Paths.get("manifest.mf"), StandardCharsets.UTF_8)
              .forEach(System.out::println);
        
    }


}

That's all about how to read the file into String in Java. Though this is good for the small tasks where you need contents of the file as String in your program, don't read a large file of few Gigabytes like that, otherwise, your Java program will run out of memory, instead use InputStream. Also, always remember to use character encoding while converting binary data to character data. If you are unsure, just use UTF-8 as default.


In reality, different file provides character encoding metadata differently e.g. XML file as that as their first line header, HTML file defines character encoding in "Content-Type" attribute and so on. If you are using XML parser then you don't need to worry as they have a way to figure out correct encoding by reading the file, same is the case if you are reading HTML using open source library.



If you like this article and want to learn more about improved file IO in recent Java version, please check following tutorials:
  • 3 ways to read a file line by line in Java 8 (examples)
  • How to read a text file line by line using BufferedReader in Java? (answer)
  • How to use a memory mapped file in Java? (answer)
  • How to read an XML file as String in Java? (tutorial)
  • How to read/write Excel (both XLS and XLSX) files in Java using Apache POI? (tutorial)
  • 2 ways to parse CSV file in Java? (answer)
  • How to read and write from/to RandomAccessFile in Java? (tutorial)
  • How to delete a directory with files in Java? (answer)
hope this helps

4 comments:

  1. @Javin well already java 7 and java 8 have come up with new advance features a lot.. but still apart from java this is the below alternative

    If you are using Java 5/6, you can use Apache Commons IO for read file to string. The class org.apache.commons.io.FileUtils contais several method for read files.

    e.g. using the method FileUtils#readFileToString:

    File file = new File("abc.txt");
    String content = FileUtils.readFileToString(file);

    ReplyDelete
  2. Since Java 11: java.nio.file.Files#readString(java.nio.file.Path)

    ReplyDelete
  3. @Unknown, that's useful, thanks for sharing.

    ReplyDelete