How to Read File in One Line in JDK 7 or Java 8

Reading a file in Java is not simple, it requires lots of boiler plate code, as we have seen in our earlier example of reading text files. Various things had to wrapped e.g. a FileInputStream inside a BufferedReader, loops with weird terminating conditions had to be specified and so forth. From JDK 7 onward,  you can do a lot better. It provides lots of useful classes e.g. Files and Paths to deal with file and their actual path. In this article, we will see how we can read a file in just one line. Of course, your production code won't be like that, especially if you are reading a few gigabytes into memory and want to pay attention to the character set, if you don't specify, by platform's default character encoding will be used.  In short, you will need a little more code, but for quick and dirty file reading this should do the trick. By the way, It wouldn't be a one-liner if it had exception handling. In a production application you would need to deal with the fact that the file isn't there e.g. displaying an error for the user, posting metrics, logging the error etc, but it certainly be lot less boiler code than it used to be.


Java 8 made life even easier with its new set of methods which take advantage of stream API. Some new methods are also added in Files class which always use UTF-8 instead of random platform encoding, for example Files.readAllLines(). This method read all lines from a file. Bytes from the file are decoded into characters using the UTF-8 charset. It's equivalent to Java 7's Files.readAllLines(path, StandardCharsets.UTF_8). BTW,  Always use explicitly character encoding while converting byte array to String. Always explicitly set your charsets, even if the file you are reading contains only English at that moment.





Reading file in one line Java 7 and 8

Here is our sample Java program to demonstrate how you can read a complete file in just one line of code. Our example uses new Files class which was introduced in JDK 1.7, the java.nio.file.Files class contains lots of utility method to deal with files in Java e.g. checking whether a file is hidden, or to check if a file is read only.  You can use Files.readAllBytes(Path) to read a complete file in memory. This method returns a byte array, which can be passed to String constructor to create String out of it. This method also ensures that file is properly closed when all bytes are read, or an IO error or other unchecked exception has occurred, which means no need to close file in finally block, in short no boiler plate coding.  BTW, this method is not suitable to read large files, because you might run out of memory if enough space is not available in heap. You should also explicitly provide character encoding while converting byte array to String to avoid any surprise or parsing error.

If you want to read file as String then you can also use another method called readAllLines(Path path, Charset cs), this method is similar to previous one i.e. it also close files after reading or in case of error but instead of returning byte array, returns a list of String, which is converted from bytes using specified character set. Further to this, Java 8 added another overloaded version of this method which doesn't require Charset and uses UTF-8 to convert bytes to String.

Goodies not ends here, if you want to read a file line by line, you can use Files.lines() method, which returns a Stream of String read from file, where bytes are converted to character using UTF-8 character encoding. By using forEach() method, you can print all lines of file into console by using just one line of Java code, as shown in third code snippet.

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 {

        // Java 7 Example - Uses Platform's default character encoding
        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 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.
++++++++++++++++++++++++


How to read File in Java 8 with Example

You can further shortened code by using static import in Java as shown below :


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"))));
    }
}


If you are using Java 8, you can also use Stream API to write more concise and performance code, as shown in following example. In this example, lines() method returns a Stream of String, which is converted from bytes read from file to character using UTF-8 character encoding. It's equivalent to Java 7, Files.lines(path, StandardCharsets.UTF_8) method call.

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 {

        // In Java 8, you can also use Streams to further optimize it
        Files.lines(Paths.get("manifest.mf"), StandardCharsets.UTF_8)
              .forEach(System.out::println);
    }


}

That's all about how to read a text or binary file in one line in Java 7. As you can, new File API of JDK 7 and new Stream API from Java 8 has made file reading quite smooth in Java. It reduced the boiler plate code completely, resulting in much cleaner and concise code. By the way, if you are writing production code for file reading then don't forget to pay attention to following points :

  • File could be large to fit in memory, so carefully examine the size before reading it and handle the situation when you cannot read file. 
  • Log why you can't read file or any error you encountered while reading file.
  • Always specify character encoding while reading bytes to characters.
  • Remember, File may not be present also, so handle that as well. 


Thanks for reading this far guys. If you enjoyed this article and hungry for more Java 8 tutorials, you will love following articles as well :
  • How to use Lambda Expression in Place of Anonymous class (solution)
  • 10 Examples of Stream API in Java (examples)
  • How to filter Collection in Java 8 using Predicates? (solution)
  • How to use Lambda expressions in Java? (examples)
  • How to use Map function in Java 8 (example)
  • 10 Java 7 Feature to revisit before you starts with Java 8 (read more)
  • How to use Default method in Java 8. (see here)
  • How to read RandomAccessFile in Java? (solution)
  • Java 8 Comparator Example (example)
  • Are you ready for Java 8 Certification? (read more)
  • Free Java 8 tutorials and Books (resources)
  • Top 10 tutorials to Learn Java 8 (tutorial)

4 comments :

Anonymous said...

If you're using Files.lines, you should probably wrap it in a try to clean up.
See:
https://docs.oracle.com/javase/8/docs/api/java/nio/file/Files.html#lines-java.nio.file.Path-java.nio.charset.Charset-

Anonymous said...

File.lines(...) - you need to close Stream. Otherwise it will lead to 'too many open files'.
Check javadocs.

Anonymous said...

That's really weired for a utility method to not complete its job. Files.lines() should have done the cleanup by itself instead of reliaing on clients to do the job. Its very easy to forget about those only to find that your programming is running out of file descriptors.

Javin Paul said...

@Anonymous 1 and 2nd, thanks for your comments but I didn't found any mention of using Files.lines and closing IO streams. Yes, it does throw IOException if any IO error happens while opening file, but no mention about specially closing it. May be you can point to the right reference.

Since Files.lines() is only available in Java 8 and main reason of using it to take advantage of lazily loaded stream API, I am expecting them to closing the file once it read.

Post a Comment