Sunday, July 24, 2022

How to read a File in One Line in Java? Files.readAllLines() Example Tutorial

Reading a file in Java is not simple, it requires lots of boilerplate code, as we have seen in our earlier example of reading text files. Various things had to be 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 like 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 like displaying an error for the user, posting metrics, logging the error, etc, but it certainly be a 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 reads 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 a file in one line Java 8? Files.readAllLines() Example

Here is our sample Java program to demonstrate how you can read a complete file in just one line of code. Our example uses a new Files class which was introduced in JDK 1.7, the java.nio.file.Files class contains lots of utility methods 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 the 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 the file in finally block, in short, no boilerplate 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 the file as String then you can also use another method called readAllLines(Path path, Charset cs), this method is similar to the 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 do not end 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 a file, where bytes are converted to a character using UTF-8 character encoding. By using the forEach() method, you can print all lines of the file into the console by using just one line of Java code, as shown in the 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 a more concise and performance code, as shown in the 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. As you can, the new File API of JDK 7 and new Stream API from Java 8 have made file reading quite smooth in Java. It reduced the boilerplate code completely, resulting in a 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 the following points :
  • The file could be large to fit in memory, so carefully examine the size before reading it and handle the situation when you cannot read the file. 
  • Log why you can't read the file or any error you encountered while reading the 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 the 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 the 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)

P.S. -  If you want to learn more about new features in Java 8 then please see these Java 8 courses. It explains all important features of Java 8 e.g. lambda expressions, streams, functional interface, Optional, new date, and time API and other miscellaneous changes.

12 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.

Anonymous said...

Quick question about ReadAllBytes() - I converted a file into byte array and stored in the database(SQL Server). I need to retrieve the byte array from database and decrypt back to the file. Is there a method for that? Or how do I go about doing that? Any help is appreciated.

javin paul said...

@Anonymous, you need to use BLOB (Binary Large object) type of SQL Server to store and retrieve that data (byte array) using JDBC. Once you get the byte array in your Java code, you can easily convert that into text. You can even use CLOB (Character large Object) if you are storing text data.

Anonymous said...

I used varbinary to store byte array in microsoft SQL server.

Anonymous said...

Do you have a link that guides me in decrypting byte array to text? Thanks in advance, I tried but did not succeed.

javin paul said...

Hello @Anonymous, once you got the byte array in Java code, you can use String constructor new String(byte[], String characterEncoding) to convert it to String or text. You can see this example for more details.

If you have trouble reading varbinary data from SQL Server then you can use getBlob(int columnIndex) method of ResultSet.

Anonymous said...

What is the default character encoding used by ReadAllBytes() ?

Anonymous said...

Nevermind, I got the answer about default encoding for platform set.

javin paul said...

cool, anyway, if you ant to learn more about Java platform's default character encoding, check my post how to get/set default character encoding in Java

Post a Comment