I am trying to read a simple text file into a String. Of course there is the usual way of getting the input stream and iterating with readLine() and reading contents into String.
Having done this hundreds of times in past, I just wondered how can I do this in minimum lines of code? Isn't there something in java like String fileContents = XXX.readFile(myFile/*File*/)
.. rather anything that looks as simple as this?
I know there are libraries like Apache Commons IO which provide such simplifications or even I can write a simple Util class to do this. But all that I wonder is - this is a so frequent operation that everyone needs then why doesn't Java provide such simple function? Isn't there really a single method somewhere to read a file into string with some default or specified encoding?
-
4Java 11 Files.readString(path) can be used to read file into string with less verbosity. howtodoinjava.com/java/io/java-read-file-to-string-examples/…Lokesh Gupta– Lokesh Gupta2023年10月22日 20:48:25 +00:00Commented Oct 22, 2023 at 20:48
9 Answers 9
Yes, you can do this in one line (though for robust IOException
handling you wouldn't want to).
String content = new Scanner(new File("filename")).useDelimiter("\\Z").next();
System.out.println(content);
This uses a java.util.Scanner
, telling it to delimit the input with \Z
, which is the end of the string anchor. This ultimately makes the input have one actual token, which is the entire file, so it can be read with one call to next()
.
There is a constructor that takes a File
and a String charSetName
(among many other overloads). These two constructor may throw FileNotFoundException
, but like all Scanner
methods, no IOException
can be thrown beyond these constructors.
You can query the Scanner
itself through the ioException()
method if an IOException
occurred or not. You may also want to explicitly close()
the Scanner
after you read the content, so perhaps storing the Scanner
reference in a local variable is best.
See also
Related questions
- Validating input using java.util.Scanner - has many examples of more typical usage
Third-party library options
For completeness, these are some really good options if you have these very reputable and highly useful third party libraries:
Guava
com.google.common.io.Files
contains many useful methods. The pertinent ones here are:
String toString(File, Charset)
- Using the given character set, reads all characters from a file into a
String
- Using the given character set, reads all characters from a file into a
List<String> readLines(File, Charset)
- ... reads all of the lines from a file into a
List<String>
, one entry per line
- ... reads all of the lines from a file into a
Apache Commons/IO
org.apache.commons.io.IOUtils
also offer similar functionality:
String toString(InputStream, String encoding)
- Using the specified character encoding, gets the contents of an
InputStream
as aString
- Using the specified character encoding, gets the contents of an
List readLines(InputStream, String encoding)
- ... as a (raw)
List
ofString
, one entry per line
- ... as a (raw)
Related questions
(削除) Most useful free third party Java libraries (deleted)? (削除ここまで)
-
2Please also see solution below for Java 7 mechanism that's essentially one line with the default API, as with many things Java has moved on slightly since this question.Jim– Jim2013年06月13日 13:45:47 +00:00Commented Jun 13, 2013 at 13:45
-
7Unfortunately, the Scanner solution fails with empty files (NoSuchElementException)Daniel Alder– Daniel Alder2014年05月15日 22:21:39 +00:00Commented May 15, 2014 at 22:21
-
2I have used this for some time, but it turns out it doesn't always work! Sometimes
\\Z
will actually occur in the file and will cause this to fail.wvdz– wvdz2014年08月20日 11:29:37 +00:00Commented Aug 20, 2014 at 11:29 -
8return new Scanner(new URL(url).openStream(), "UTF-8").useDelimiter("\\A").next(); is better as it does not fail on empty files.Guy– Guy2015年01月04日 17:40:46 +00:00Commented Jan 4, 2015 at 17:40
-
2Avoid this, if you are using text files that are bigger than 1024 bytes. The scanner will (at least on Android) cuts the resulting string to 1024 bytes.Udo Klimaschewski– Udo Klimaschewski2017年02月10日 10:51:44 +00:00Commented Feb 10, 2017 at 10:51
From Java 7 (API Description) onwards you can do:
new String(Files.readAllBytes(Paths.get(filePath)), StandardCharsets.UTF_8);
Where filePath is a String representing the file you want to load.
-
2I believe this will only work if the file was in the platform's default char set.Paul– Paul2013年06月24日 10:01:24 +00:00Commented Jun 24, 2013 at 10:01
-
7@Paul that would be okay as a default I think. You can always specify a charset when constructing the new StringMike Braun– Mike Braun2013年06月30日 19:20:08 +00:00Commented Jun 30, 2013 at 19:20
-
2This solution has the disadvantage of not working with classpath resources (obtained via
Class.getResource()
or similar methods), while theScanner
solution does work in this case.LordOfThePigs– LordOfThePigs2014年10月06日 19:29:00 +00:00Commented Oct 6, 2014 at 19:29 -
2a pure java version of my last comment: String iAmAString = new String(Files.readAllBytes(new File(Thread.currentThread().getContextClassLoader().getResource("iAmAFile").toURI()).toPath()));Rondo– Rondo2015年01月17日 01:50:22 +00:00Commented Jan 17, 2015 at 1:50
-
5Since Java 11:
String s = Files.readString(Paths.get(filePath))
Mikolasan– Mikolasan2020年11月17日 09:52:26 +00:00Commented Nov 17, 2020 at 9:52
You can use apache commons IO..
FileInputStream fisTargetFile = new FileInputStream(new File("test.txt"));
String targetFileStr = IOUtils.toString(fisTargetFile, "UTF-8");
-
19What is it with Java programmers and always trying to use third party libraries when Java has built in facilities that work just fine.user84118– user841182014年02月15日 00:57:20 +00:00Commented Feb 15, 2014 at 0:57
-
5Of course those facilities "work just fine", it's just that some of them are utterly over-complicated. I agree however that using another lib just for this is a bit overkill.Andrea Lazzarotto– Andrea Lazzarotto2014年08月18日 09:21:04 +00:00Commented Aug 18, 2014 at 9:21
-
4It is not overkill. It is an opportunity. The opportunity to start using the apache commons libraries and become productive. Or you can opt for guava.Florian F– Florian F2017年08月29日 10:56:45 +00:00Commented Aug 29, 2017 at 10:56
-
1It's a three-liner - you'll need to cose the stream.Pavel Vlasov– Pavel Vlasov2020年08月05日 13:14:46 +00:00Commented Aug 5, 2020 at 13:14
This should work for you:
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
public static void main(String[] args) throws IOException {
String content = new String(Files.readAllBytes(Paths.get("abc.java")));
}
-
1Thanks! In contrast to the majority solution, this also doesn’t remove the trailing newline. One improvement:
new String(..., StandardCharsets.UTF_8)
mirabilos– mirabilos2019年03月21日 17:25:38 +00:00Commented Mar 21, 2019 at 17:25
Using Apache Commons IO.
import org.apache.commons.io.FileUtils;
//...
String contents = FileUtils.readFileToString(new File("/path/to/the/file"), "UTF-8")
You can see de javadoc for the method for details.
Don't write your own util class to do this - I would recommend using Guava, which is full of all kinds of goodness. In this case you'd want either the Files
class (if you're really just reading a file) or CharStreams for more general purpose reading. It has methods to read the data into a list of strings (readLines
) or totally (toString
).
It has similar useful methods for binary data too. And then there's the rest of the library...
I agree it's annoying that there's nothing similar in the standard libraries. Heck, just being able to supply a CharSet
to a FileReader
would make life a little simpler...
-
1On Java 7, would you recommend Guava or
new String(Files.readAllBytes(Paths.get(filePath)))
?Manu Manjunath– Manu Manjunath2014年07月09日 07:24:34 +00:00Commented Jul 9, 2014 at 7:24 -
2@Manu: I'd definitely not use that - I'd at least specify a character encoding. But as Guava is generally useful anyway (even with Java 8) you might as well use
Files.toString
given how easy it is...Jon Skeet– Jon Skeet2014年07月09日 07:32:59 +00:00Commented Jul 9, 2014 at 7:32
Another alternative approach is:
How do I create a Java string from the contents of a file?
Other option is to use utilities provided open source libraries
http://commons.apache.org/io/api-1.4/index.html?org/apache/commons/io/IOUtils.html
Why java doesn't provide such a common util API ?
a) to keep the APIs generic so that encoding, buffering etc is handled by the programmer.
b) make programmers do some work and write/share opensource util libraries :D ;-)
Sadly, no.
I agree that such frequent operation should have easier implementation than copying of input line by line in loop, but you'll have to either write helper method or use external library.
I discovered that the accepted answer actually doesn't always work, because \\Z
may occur in the file. Another problem is that if you don't have the correct charset a whole bunch of unexpected things may happen which may cause the scanner to read only a part of the file.
The solution is to use a delimiter which you are certain will never occur in the file. However, this is theoretically impossible. What we CAN do, is use a delimiter that has such a small chance to occur in the file that it is negligible: such a delimiter is a UUID, which is natively supported in Java.
String content = new Scanner(file, "UTF-8")
.useDelimiter(UUID.randomUUID().toString()).next();
-
1What do you mean by "\\Z may occur in the file"? \Z (after unescaping) is one of the patterns of java.util.regex.Pattern, not the literal character sequence. The literal character sequence, a backslash followed by Z, in the file would not match with the pattern \Z.Kuro– Kuro2017年12月20日 17:43:25 +00:00Commented Dec 20, 2017 at 17:43
-
@KuroKurosaka I don't mean the literal sequence
\Z
, I mean the file may actually contain the 'End of string' character somewhere in the middle of the file. It happened to me, and was the reason the accepted answer did not work for me.wvdz– wvdz2018年01月06日 11:12:34 +00:00Commented Jan 6, 2018 at 11:12 -
I see. You are thinking of a situation where a piece of software or OS decided to use a control character other than CR or LF (or both, in case of Microsoft) for the EOL sequence. I'd write it something like "'\u001A', for example, if Control-Z is used to as the EOF character".Kuro– Kuro2018年01月07日 19:15:32 +00:00Commented Jan 7, 2018 at 19:15