Adam Bien's Weblog

Reading A File Into A String - With A Single Line And JDK 1.6+


import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;

public class ScannerSample {

    public static void main(String[] args) throws FileNotFoundException {
     //Z means: "The end of the input but for the final terminator, if any"
        String output = new Scanner(new File("file.txt")).useDelimiter("\\Z").next();
        System.out.println("" + output);
    }
}


[Thanks Paulo Silveira for the snippet!]


NEW workshop: Microservices with Java EE 7 and Java 8, January 26th, 2015, Airport Munich

A book about rethinking Java EE Patterns

Comments:

Nice Java 6 hack. Scanner is so underestimated :-)

Posted by Marcus K. on September 19, 2011 at 02:04 PM CEST #

Scanner is generally great, but it's based on regular expression, so the performance could become bad in some situations. I remember I did a test to read a large text file line by line, and it turned out BufferedReader.readLine() is much more effective than Scanner.nextLine().

Posted by shinzey on September 19, 2011 at 03:21 PM CEST #

Adam, you have a typo in that code snippet.
It should be new File("file.txt") instead of new File("file.txt)
(see the missing ").

Posted by Maciej Biłas on September 19, 2011 at 03:48 PM CEST #

@Maciej,

thanks! Corrected that. In my working example looked like:

File file = new File("./file.txt");
String output = new Scanner(file).useDelimiter("\\Z").next();

but I shortened it for the post. This is the reason for the typo.

Thanks!,

adam

Posted by Adam Bien on September 19, 2011 at 11:59 PM CEST #

@Shinzey

Premature Optimization Is The Root Of All Over-Engineering :-). But you are right. The compilation of regexes is noticeable. I try always to measure the performance before I optimize it.

With NetBeans it is just another button to hit :-)

thanks for your comment!,

adam

Posted by Adam Bien on September 20, 2011 at 12:02 AM CEST #

This idiom is used in the German book "Java ist auch eine Insel" for several years. But it has a mayor problem: the underlying ReadableByteChannel is not closed and this is a resource leak (same with your Files.newBufferedReader() examples, you don't close them). Starting with Java 7 try-with-resources is nice helper because Scanner is Closeable and thus AutoCloseable.

Posted by Christian on September 20, 2011 at 12:08 AM CEST #

Thank you for this interesting post Adam!

Posted by 88.149.245.206 on September 20, 2011 at 03:00 AM CEST #

Thanks for introducing me to Scanner. I had not seen it before and we can use it in our current project.

It is also present in Java 5.0.

Posted by Michael Strasser on September 20, 2011 at 11:37 AM CEST #

Thanks for the credits. As Michael Strasser pointed out, it is valid since Java 5.

Although pratical, we need to be careful: if scanning a InputStream like System.in or a socket one, it will only return from the .next() invocation when EOF is found.

Posted by Paulo Silveira on September 20, 2011 at 06:48 PM CEST #

Hi Adam,

thanks for pointing out Scanner, I never stumpled over that but used commons-io for such tasks.
But I think it would be worth mentioning that Scanner support charsets as well when reading from files or input streams because lots of people tend to forget that and rely on system charset.

See you on W-JAX,
Stephan

Posted by Stephan on October 30, 2011 at 11:42 PM CET #

Hi everybody
This code doesn't work if charset of file is differs with UTF-8

Posted by Victor on June 08, 2012 at 05:50 PM CEST #

This solution eats the the last new line in the file. I tried \Z and $. Both do not work.

Posted by 193.254.155.48 on September 27, 2012 at 03:28 PM CEST #

Scanner is evil. We'd recommend to simply use BufferedReader's read(...) methods instead. Faster (!) and safer than using Scanner (why safer? search the web for examples, or wait until your Scanner decides to return some multiple of 1024 bytes instead of the entire file, for example).

Example implementation below, hopefully without typos.

public static String readEntireFileAsString(String filename) {

BufferedReader br = null;
try {
StringBuffer sb = new StringBuffer();

br = new BufferedReader(new InputStreamReader(new FileInputStream(filename), "UTF-8"));

char[] buf = new char[1024];
int i=0;
while((i=br.read(buf)) != -1) {
fileData.append(String.valueOf(buf, 0, numRead));
buf = new char[1024];
}
return sb.toString();
} catch (IOException e) {
// Ignore silently, e.g. "return null" or leave it to be thrown (then add 'throws' declaration above...)
} finally {
if (br!=null) try {br.close();} catch (Exception e) {}
}

}

p.s. if you liked this, please consider donating us a LIKE on Facebook ;)

Posted by StatsTrade on October 04, 2012 at 02:53 PM CEST #

Hi all,
i have used scanner, when i have an xml of long content, it's just returning me only 1024 bytes.
private static File replaceInvalidString(String Target, String Dest,
File Source) throws IOException {
String xml_string;

xml_string = new Scanner(Source).useDelimiter("\\Z").next();

xml_string = xml_string.replace(Target, Dest);

FileOutputStream fi = new FileOutputStream(Source);

fi.write(xml_string.getBytes());

return Source;
}

Posted by Pavan on October 24, 2013 at 12:18 AM CEST #

Post a Comment:
  • HTML Syntax: NOT allowed
realworldpatterns.com
...the last 150 posts
...the last 10 comments
License