Reputation: 199304
I've been using the idiom below for some time now. And it seems to be the most wide-spread, at least on the sites I've visited.
Is there a better/different way to read a file into a string in Java?
private String readFile(String file) throws IOException {
BufferedReader reader = new BufferedReader(new FileReader (file));
String line = null;
StringBuilder stringBuilder = new StringBuilder();
String ls = System.getProperty("line.separator");
try {
while((line = reader.readLine()) != null) {
stringBuilder.append(line);
stringBuilder.append(ls);
}
return stringBuilder.toString();
} finally {
reader.close();
}
}
Upvotes: 1798
Views: 1751942
Reputation: 5871
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
Java 7
String content = new String(Files.readAllBytes(Paths.get("readMe.txt")), StandardCharsets.UTF_8);
Java 11
String content = Files.readString(Path.of("readMe.txt"));
Upvotes: 169
Reputation: 63
Using BufferedReader as mentioned in comments before but this way is more readable:
String FILE_PATH = "filepath.txt";
try (FileReader fileReader = new FileReader(FILE_PATH)) {
BufferedReader fileBufferReader = new BufferedReader(fileReader);
String text = fileBufferReader.lines()
.collect(Collectors.joining(System.lineSeparator()));
System.out.println(text);
} catch (IOException e) {
// exception handling
}
Upvotes: 1
Reputation: 883
Works on all android versions
val fileAsString = file.bufferedReader().use { it.readText() }
Upvotes: -1
Reputation: 269827
Java 11 added the readString() method to read small files as a String
, preserving line terminators:
String content = Files.readString(path, encoding);
For versions between Java 7 and 11, here's a compact, robust idiom, wrapped up in a utility method:
static String readFile(String path, Charset encoding)
throws IOException
{
byte[] encoded = Files.readAllBytes(Paths.get(path));
return new String(encoded, encoding);
}
Java 7 added a convenience method to read a file as lines of text, represented as a List<String>
. This approach is "lossy" because the line separators are stripped from the end of each line.
List<String> lines = Files.readAllLines(Paths.get(path), encoding);
Java 8 added the Files.lines()
method to produce a Stream<String>
. Again, this method is lossy because line separators are stripped. If an IOException
is encountered while reading the file, it is wrapped in an UncheckedIOException
, since Stream
doesn't accept lambdas that throw checked exceptions.
try (Stream<String> lines = Files.lines(path, encoding)) {
lines.forEach(System.out::println);
}
This Stream
does need a close()
call; this is poorly documented on the API, and I suspect many people don't even notice Stream
has a close()
method. Be sure to use an ARM-block as shown.
If you are working with a source other than a file, you can use the lines()
method in BufferedReader
instead.
If your file is small enough relative to your available memory, reading the entire file at once might work fine. However, if your file is too large, reading one line at a time, processing it, and then discarding it before moving on to the next could be a better approach. Stream processing in this way can eliminate the total file size as a factor in your memory requirement.
One thing that is missing from the sample in the original post is the character encoding. This encoding generally can't be determined from the file itself, and requires meta-data such as an HTTP header to convey this important information.
The StandardCharsets
class defines some constants for the encodings required of all Java runtimes:
String content = readFile("test.txt", StandardCharsets.UTF_8);
The platform default is available from the Charset
class itself:
String content = readFile("test.txt", Charset.defaultCharset());
There are some special cases where the platform default is what you want, but they are rare. You should be able justify your choice, because the platform default is not portable. One example where it might be correct is when reading standard input or writing standard output.
Note: This answer largely replaces my Java 6 version. The utility of Java 7 safely simplifies the code, and the old answer, which used a mapped byte buffer, prevented the file that was read from being deleted until the mapped buffer was garbage collected. You can view the old version via the "edited" link on this answer.
Upvotes: 1870
Reputation: 13057
With Java 7, this is my preferred option to read a UTF-8 file:
String content = new String(Files.readAllBytes(Paths.get(filename)), "UTF-8");
Since Java 7, the JDK has the new java.nio.file
API, which provides many shortcuts, so 3rd party libraries are not always required for simple file operations.
Since people are still upvoting this answer, here is a better solution that got introduced in Java 11:
String content = Files.readString(path);
Upvotes: 17
Reputation: 139
Scanner sc = new Scanner(new File("yourFile.txt"));
sc.useDelimiter("\\Z");
String s = sc.next();
Upvotes: 0
Reputation: 48659
Guava has a method similar to the one from Commons IOUtils that Willi aus Rohr mentioned:
import com.google.common.base.Charsets;
import com.google.common.io.Files;
// ...
String text = Files.toString(new File(path), Charsets.UTF_8);
EDIT by PiggyPiglet
Files#toString
is deprecated, and due for removal Octobor 2019. Instead use
Files.asCharSource(new File(path), StandardCharsets.UTF_8).read();
EDIT by Oscar Reyes
This is the (simplified) underlying code on the cited library:
InputStream in = new FileInputStream(file);
byte[] b = new byte[file.length()];
int len = b.length;
int total = 0;
while (total < len) {
int result = in.read(b, total, len - total);
if (result == -1) {
break;
}
total += result;
}
return new String( b , Charsets.UTF_8 );
Edit (by Jonik): The above doesn't match the source code of recent Guava versions. For the current source, see the classes Files, CharStreams, ByteSource and CharSource in com.google.common.io package.
Upvotes: 73
Reputation: 5045
A very lean solution based on Scanner
:
Scanner scanner = new Scanner( new File("poem.txt") );
String text = scanner.useDelimiter("\\A").next();
scanner.close(); // Put this call in a finally block
Or, if you want to set the charset:
Scanner scanner = new Scanner( new File("poem.txt"), "UTF-8" );
String text = scanner.useDelimiter("\\A").next();
scanner.close(); // Put this call in a finally block
Or, with a try-with-resources block, which will call scanner.close()
for you:
try (Scanner scanner = new Scanner( new File("poem.txt"), "UTF-8" )) {
String text = scanner.useDelimiter("\\A").next();
}
Remember that the Scanner
constructor can throw an IOException
. And don't forget to import java.io
and java.util
.
Source: Pat Niemeyer's blog
Upvotes: 190
Reputation: 4898
If you're willing to use an external library, check out Apache Commons IO (200KB JAR). It contains an org.apache.commons.io.FileUtils.readFileToString()
method that allows you to read an entire File
into a String
with one line of code.
Example:
import java.io.*;
import java.nio.charset.*;
import org.apache.commons.io.*;
public String readFile() throws IOException {
File file = new File("data.txt");
return FileUtils.readFileToString(file, StandardCharsets.UTF_8);
}
Upvotes: 406
Reputation: 1147
public static String slurp (final File file)
throws IOException {
StringBuilder result = new StringBuilder();
BufferedReader reader = new BufferedReader(new FileReader(file));
try {
char[] buf = new char[1024];
int r = 0;
while ((r = reader.read(buf)) != -1) {
result.append(buf, 0, r);
}
}
finally {
reader.close();
}
return result.toString();
}
Upvotes: 3
Reputation: 32271
If you do not have access to the Files
class, you can use a native solution.
static String readFile(File file, String charset)
throws IOException
{
FileInputStream fileInputStream = new FileInputStream(file);
byte[] buffer = new byte[fileInputStream.available()];
int length = fileInputStream.read(buffer);
fileInputStream.close();
return new String(buffer, 0, length, charset);
}
Upvotes: 7
Reputation: 2911
User java.nio.Files
to read all lines of file.
public String readFile() throws IOException {
File fileToRead = new File("file path");
List<String> fileLines = Files.readAllLines(fileToRead.toPath());
return StringUtils.join(fileLines, StringUtils.EMPTY);
}
Upvotes: 3
Reputation: 187379
If you're looking for an alternative that doesn't involve a third-party library (e.g. Commons I/O), you can use the Scanner class:
private String readFile(String pathname) throws IOException {
File file = new File(pathname);
StringBuilder fileContents = new StringBuilder((int)file.length());
try (Scanner scanner = new Scanner(file)) {
while(scanner.hasNextLine()) {
fileContents.append(scanner.nextLine() + System.lineSeparator());
}
return fileContents.toString();
}
}
Upvotes: 81
Reputation: 9588
Gathered all the possible ways to read the File as String from Disk or Network.
Guava: Google using classes Resources
, Files
static Charset charset = com.google.common.base.Charsets.UTF_8;
public static String guava_ServerFile( URL url ) throws IOException {
return Resources.toString( url, charset );
}
public static String guava_DiskFile( File file ) throws IOException {
return Files.toString( file, charset );
}
APACHE - COMMONS IO using classes IOUtils, FileUtils
static Charset encoding = org.apache.commons.io.Charsets.UTF_8;
public static String commons_IOUtils( URL url ) throws IOException {
java.io.InputStream in = url.openStream();
try {
return IOUtils.toString( in, encoding );
} finally {
IOUtils.closeQuietly(in);
}
}
public static String commons_FileUtils( File file ) throws IOException {
return FileUtils.readFileToString( file, encoding );
/*List<String> lines = FileUtils.readLines( fileName, encoding );
return lines.stream().collect( Collectors.joining("\n") );*/
}
Java 8 BufferReader using Stream API
public static String streamURL_Buffer( URL url ) throws IOException {
java.io.InputStream source = url.openStream();
BufferedReader reader = new BufferedReader( new InputStreamReader( source ) );
//List<String> lines = reader.lines().collect( Collectors.toList() );
return reader.lines().collect( Collectors.joining( System.lineSeparator() ) );
}
public static String streamFile_Buffer( File file ) throws IOException {
BufferedReader reader = new BufferedReader( new FileReader( file ) );
return reader.lines().collect(Collectors.joining(System.lineSeparator()));
}
Scanner Class with regex \A
. which matches the beginning of input.
static String charsetName = java.nio.charset.StandardCharsets.UTF_8.toString();
public static String streamURL_Scanner( URL url ) throws IOException {
java.io.InputStream source = url.openStream();
Scanner scanner = new Scanner(source, charsetName).useDelimiter("\\A");
return scanner.hasNext() ? scanner.next() : "";
}
public static String streamFile_Scanner( File file ) throws IOException {
Scanner scanner = new Scanner(file, charsetName).useDelimiter("\\A");
return scanner.hasNext() ? scanner.next() : "";
}
Java 7 (java.nio.file.Files.readAllBytes
)
public static String getDiskFile_Java7( File file ) throws IOException {
byte[] readAllBytes = java.nio.file.Files.readAllBytes(Paths.get( file.getAbsolutePath() ));
return new String( readAllBytes );
}
BufferedReader
using InputStreamReader
.
public static String getDiskFile_Lines( File file ) throws IOException {
StringBuffer text = new StringBuffer();
FileInputStream fileStream = new FileInputStream( file );
BufferedReader br = new BufferedReader( new InputStreamReader( fileStream ) );
for ( String line; (line = br.readLine()) != null; )
text.append( line + System.lineSeparator() );
return text.toString();
}
Example with main method to access the above methods.
public static void main(String[] args) throws IOException {
String fileName = "E:/parametarisation.csv";
File file = new File( fileName );
String fileStream = commons_FileUtils( file );
// guava_DiskFile( file );
// streamFile_Buffer( file );
// getDiskFile_Java7( file );
// getDiskFile_Lines( file );
System.out.println( " File Over Disk : \n"+ fileStream );
try {
String src = "https://code.jquery.com/jquery-3.2.1.js";
URL url = new URL( src );
String urlStream = commons_IOUtils( url );
// guava_ServerFile( url );
// streamURL_Scanner( url );
// streamURL_Buffer( url );
System.out.println( " File Over Network : \n"+ urlStream );
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
@see
Upvotes: 33
Reputation: 16890
no external libraries used
You can create a new String object from the file content (Using classes from java.nio.file
package):
public String readStringFromFile(String filePath) throws IOException {
String fileContent = new String(Files.readAllBytes(Paths.get(filePath)));
return fileContent;
}
Upvotes: 11
Reputation: 15313
Since JDK 11:
String file = ...
Path path = Paths.get(file);
String content = Files.readString(path);
// Or readString(path, someCharset), if you need a Charset different from UTF-8
Upvotes: 26
Reputation: 480
Based on @erickson`s answer, you can use:
public String readAll(String fileName) throws IOException {
List<String> lines = Files.readAllLines(new File(fileName).toPath());
return String.join("\n", lines.toArray(new String[lines.size()]));
}
Upvotes: 3
Reputation: 271
If it's a text file why not use apache commons-io?
It has the following method
public static String readFileToString(File file) throws IOException
If you want the lines as a list use
public static List<String> readLines(File file) throws IOException
Upvotes: 27
Reputation: 1502985
That code will normalize line breaks, which may or may not be what you really want to do.
Here's an alternative which doesn't do that, and which is (IMO) simpler to understand than the NIO code (although it still uses java.nio.charset.Charset
):
public static String readFile(String file, String csName)
throws IOException {
Charset cs = Charset.forName(csName);
return readFile(file, cs);
}
public static String readFile(String file, Charset cs)
throws IOException {
// No real need to close the BufferedReader/InputStreamReader
// as they're only wrapping the stream
FileInputStream stream = new FileInputStream(file);
try {
Reader reader = new BufferedReader(new InputStreamReader(stream, cs));
StringBuilder builder = new StringBuilder();
char[] buffer = new char[8192];
int read;
while ((read = reader.read(buffer, 0, buffer.length)) > 0) {
builder.append(buffer, 0, read);
}
return builder.toString();
} finally {
// Potential issue here: if this throws an IOException,
// it will mask any others. Normally I'd use a utility
// method which would log exceptions and swallow them
stream.close();
}
}
Upvotes: 51
Reputation: 1092
In one line (Java 8), assuming you have a Reader:
String sMessage = String.join("\n", reader.lines().collect(Collectors.toList()));
Upvotes: 2
Reputation: 199304
Also if your file happens to be inside a jar, you can also use this:
public String fromFileInJar(String path) {
try ( Scanner scanner
= new Scanner(getClass().getResourceAsStream(path))) {
return scanner.useDelimiter("\\A").next();
}
}
The path should start with /
for instance if your jar is
my.jar/com/some/thing/a.txt
Then you want to invoke it like this:
String myTxt = fromFileInJar("/com/com/thing/a.txt");
Upvotes: 2
Reputation: 554
You can try Scanner and File class, a few lines solution
try
{
String content = new Scanner(new File("file.txt")).useDelimiter("\\Z").next();
System.out.println(content);
}
catch(FileNotFoundException e)
{
System.out.println("not found!");
}
Upvotes: 3
Reputation: 781
Use code:
File file = new File("input.txt");
BufferedInputStream bin = new BufferedInputStream(new FileInputStream(
file));
byte[] buffer = new byte[(int) file.length()];
bin.read(buffer);
String fileStr = new String(buffer);
fileStr contains output in String.
Upvotes: 1
Reputation: 11484
Using this library, it is one line:
String data = IO.from(new File("data.txt")).toString();
Upvotes: 3
Reputation:
in java 8 , there are a new Class
java.util.stream.Stream
A stream represents a sequence of elements and supports different kind of operations to perform computations upon those elements
to Read more about it :
Here an Example :
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.stream.Stream;
public Class ReadFile{
public static String readFile(String filePath) {
StringBuilder stringBuilder = new StringBuilder();
String ls = System.getProperty("line.separator");
try {
try (Stream<String> lines = Files.lines(Paths.get(filePath), StandardCharsets.UTF_8)) {
for (String line : (Iterable<String>) lines::iterator) {
stringBuilder.append(line);
stringBuilder.append(ls);
}
}
} catch (Exception e) {
e.printStackTrace();
}
return stringBuilder.toString();
}
}
Upvotes: -2
Reputation: 830
A flexible solution using IOUtils from Apache commons-io in combination with StringWriter:
Reader input = new FileReader();
StringWriter output = new StringWriter();
try {
IOUtils.copy(input, output);
} finally {
input.close();
}
String fileContents = output.toString();
It works with any reader or input stream (not just with files), for example when reading from a URL.
Upvotes: 4
Reputation: 4856
If you need a string processing (parallel processing) Java 8 has the great Stream API.
String result = Files.lines(Paths.get("file.txt"))
.parallel() // for parallel processing
.map(String::trim) // to change line
.filter(line -> line.length() > 2) // to filter some lines by a predicate
.collect(Collectors.joining()); // to join lines
More examples are available in JDK samples sample/lambda/BulkDataOperations
that can be downloaded from Oracle Java SE 8 download page
Another one liner example
String out = String.join("\n", Files.readAllLines(Paths.get("file.txt")));
Upvotes: 53
Reputation: 1037
After Ctrl+F'ing after Scanner, I think that the Scanner solution should be listed too. In the easiest to read fashion it goes like this:
public String fileToString(File file, Charset charset) {
Scanner fileReader = new Scanner(file, charset);
fileReader.useDelimiter("\\Z"); // \Z means EOF.
String out = fileReader.next();
fileReader.close();
return out;
}
If you use Java 7 or newer (and you really should) consider using try-with-resources to make the code easier to read. No more dot-close stuff littering everything. But that's mostly a stylistic choice methinks.
I'm posting this mostly for completionism, since if you need to do this a lot, there should be things in java.nio.file.Files that should do the job better.
My suggestion would be to use Files#readAllBytes(Path) to grab all the bytes, and feed it to new String(byte[] Charset) to get a String out of it that you can trust. Charsets will be mean to you during your lifetime, so beware of this stuff now.
Others have given code and stuff, and I don't want to steal their glory. ;)
Upvotes: 2
Reputation: 11270
This one uses the method RandomAccessFile.readFully
, it seems to be available from JDK 1.0 !
public static String readFileContent(String filename, Charset charset) throws IOException {
RandomAccessFile raf = null;
try {
raf = new RandomAccessFile(filename, "r");
byte[] buffer = new byte[(int)raf.length()];
raf.readFully(buffer);
return new String(buffer, charset);
} finally {
closeStream(raf);
}
}
private static void closeStream(Closeable c) {
if (c != null) {
try {
c.close();
} catch (IOException ex) {
// do nothing
}
}
}
Upvotes: 3
Reputation: 520
I cannot comment other entries yet, so I'll just leave it here.
One of best answers here (https://stackoverflow.com/a/326448/1521167):
private String readFile(String pathname) throws IOException {
File file = new File(pathname);
StringBuilder fileContents = new StringBuilder((int)file.length());
Scanner scanner = new Scanner(file);
String lineSeparator = System.getProperty("line.separator");
try {
while(scanner.hasNextLine()) {
fileContents.append(scanner.nextLine() + lineSeparator);
}
return fileContents.toString();
} finally {
scanner.close();
}
}
still has one flaw. It always puts new line char in the end of string, which may cause some weirds bugs. My suggestion is to change it to:
private String readFile(String pathname) throws IOException {
File file = new File(pathname);
StringBuilder fileContents = new StringBuilder((int) file.length());
Scanner scanner = new Scanner(new BufferedReader(new FileReader(file)));
String lineSeparator = System.getProperty("line.separator");
try {
if (scanner.hasNextLine()) {
fileContents.append(scanner.nextLine());
}
while (scanner.hasNextLine()) {
fileContents.append(lineSeparator + scanner.nextLine());
}
return fileContents.toString();
} finally {
scanner.close();
}
}
Upvotes: 2