Reading a textfile into a single String?

D

Digital Puer

Hi, I'm trying to read multiple text lines from a file into a single
String. The approach I am using is to read each line of the file
with BufferedReader.readLine() and appending it to a String,
but this is really slow:

BufferedReader br = new BufferedReader(fr);
String buffer, result;
while ((buffer = br.readLine()) != null) {
result = result + buffer;
}

Is there a better, faster way?
 
T

tom fredriksen

Digital said:
Hi, I'm trying to read multiple text lines from a file into a single
String. The approach I am using is to read each line of the file
with BufferedReader.readLine() and appending it to a String,
but this is really slow:

BufferedReader br = new BufferedReader(fr);
String buffer, result;
while ((buffer = br.readLine()) != null) {
result = result + buffer;
}

first of all you should be using StringBuffer.append() instead of String
concatenation, its many many times faster.

Secondly, there is nothing stopping you from using the method
BufferedReader.read(char []...)
with a char array of, say, 1-8 KB, which you add to the StringBuffer
repeatedly. Just make sure you set the size of the BufferedReader to at
least the array size.

/tom
 
J

Jeffrey Schwab

Digital said:
Hi, I'm trying to read multiple text lines from a file into a single
String. The approach I am using is to read each line of the file
with BufferedReader.readLine() and appending it to a String,
but this is really slow:

BufferedReader br = new BufferedReader(fr);
String buffer, result;
while ((buffer = br.readLine()) != null) {
result = result + buffer;

On the first pass, "result" has not been initialized.
}

Is there a better, faster way?

Use a StringBuilder or a StringBuffer. The StringBuilder theoretically
should be a little faster, because it does not provide any guarantee of
synchronization. On my system, they are equally fast. In the program
below, each takes ~300ms to process the input file, plus a 50-ms hit to
whichever is tested first. Here's the output of a run on my system:
java -cp . Main
Using a StringBuilder took 350 ms.
Using a StringBuffer took 301 ms.
^C

OK, so I killed the String test. It was slowing down my machine.
Here's the code:

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.IOException;
import java.io.Reader;
import java.util.Date;

class Main {

static String readWithString(Reader fr)
throws IOException {

BufferedReader br = new BufferedReader(fr);
String buffer, result = "";
while ((buffer = br.readLine()) != null) {
result = result + buffer;
}

return result;
}

static String readWithStringBuffer(Reader fr)
throws IOException {

BufferedReader br = new BufferedReader(fr);
String line;
StringBuffer result = new StringBuffer();
while ((line = br.readLine()) != null) {
result.append(line);
}

return result.toString();
}

static String readWithStringBuilder(Reader fr)
throws IOException {

BufferedReader br = new BufferedReader(fr);
String line;
StringBuilder result = new StringBuilder();
while ((line = br.readLine()) != null) {
result.append(line);
}

return result.toString();
}

public static void main(String[] args)
throws IOException {

/* Using each of several buffer types, record the time taken to
* concatenate all lines from a text file, without newlines.
*
* The sample text file is ~ 3MB, courtesy of Project Gutenberg.
* http://www.gutenberg.org/
*/

FileReader f = new FileReader("war_and_peace.txt"); // ~3MB

try {

long t = new Date().getTime();
readWithStringBuilder(f);
t = new Date().getTime() - t;
System.out.println(
"Using a StringBuilder took " + t + " ms.");
} finally {
f.close();
}

f = new FileReader("war_and_peace.txt"); // ~3MB.

try {
long t = new Date().getTime();
readWithStringBuffer(f);
t = new Date().getTime() - t;
System.out.println(
"Using a StringBuffer took " + t + " ms.");
} finally {
f.close();
}

f = new FileReader("war_and_peace.txt"); // ~3MB.

try {
long t = new Date().getTime();
readWithString(f);
t = new Date().getTime() - t;
System.out.println(
"Using a String took " + t + " ms.");
} finally {
f.close();
}
}
}
 
J

Jeffrey Schwab

tom said:
Digital Puer wrote:
BufferedReader br = new BufferedReader(fr);
String buffer, result;
while ((buffer = br.readLine()) != null) {
result = result + buffer;
}
....

Secondly, there is nothing stopping you from using the method
BufferedReader.read(char []...)
with a char array of, say, 1-8 KB, which you add to the StringBuffer
repeatedly. Just make sure you set the size of the BufferedReader to at
least the array size.

That's a much nicer solution. It is a little different from the
original though, in that it preserves line terminators.
 
D

Digital Puer

Thank you for the clear explanation.



tom said:
Digital said:
Hi, I'm trying to read multiple text lines from a file into a single
String. The approach I am using is to read each line of the file
with BufferedReader.readLine() and appending it to a String,
but this is really slow:

BufferedReader br = new BufferedReader(fr);
String buffer, result;
while ((buffer = br.readLine()) != null) {
result = result + buffer;
}

first of all you should be using StringBuffer.append() instead of String
concatenation, its many many times faster.

Secondly, there is nothing stopping you from using the method
BufferedReader.read(char []...)
with a char array of, say, 1-8 KB, which you add to the StringBuffer
repeatedly. Just make sure you set the size of the BufferedReader to at
least the array size.

/tom
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top