Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Read file

2 views
Skip to first unread message

Anabolik

unread,
Jul 30, 2009, 3:56:40 AM7/30/09
to
I try to read the content of file text.txt. The size of this file is
26 Mb. And always I have the error:

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at java.util.Arrays.copyOf(Arrays.java:2882)
at java.lang.AbstractStringBuilder.expandCapacity
(AbstractStringBuilder.java:100)
at java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:
390)
at java.lang.StringBuffer.append(StringBuffer.java:224)

at lines contents.append(text).append(System.getProperty
("line.separator"));

How can I read and save the content of file. The content of file I
need then in the program to show it in some dialog.

public static void main(String[] args) {
File file = new File("D:\\work\\text.txt");
StringBuffer contents = new StringBuffer();
BufferedReader reader = null;

try {
reader = new BufferedReader(new FileReader(file));
String text = null;

// repeat until all lines is read
while ((text = reader.readLine()) != null)
{
contents.append(text).append(System.getProperty
("line.separator"));
}
} catch (FileNotFoundException e)
{
e.printStackTrace();
} catch (IOException e)
{
e.printStackTrace();
} finally
{
try
{
if (reader != null)
{
reader.close();
}
} catch (IOException e)
{
e.printStackTrace();
}
}

// show file contents here
System.out.println(contents.toString());
}

Sabine Dinis Blochberger

unread,
Jul 30, 2009, 4:17:39 AM7/30/09
to
Anabolik wrote:

> I try to read the content of file text.txt. The size of this file is
> 26 Mb. And always I have the error:
>
> Exception in thread "main" java.lang.OutOfMemoryError: Java heap space

Putting "java heap space" in a search engine gave me the following
helpful link:
<http://www.jguru.com/faq/view.jsp?EID=1300058>

You will have to increase the available heap space.
--
Op3racional - www.op3racional.eu
---------------------
If you're reading this, you're on Usenet
<http://oakroadsystems.com/genl/unice.htm>

Anabolik

unread,
Jul 30, 2009, 4:20:40 AM7/30/09
to
I increased but it did not help.

Sabine Dinis Blochberger

unread,
Jul 30, 2009, 4:40:06 AM7/30/09
to
Anabolik wrote:

> I increased but it did not help.

Be more specific.

rossum

unread,
Jul 30, 2009, 5:03:13 AM7/30/09
to
On Thu, 30 Jul 2009 00:56:40 -0700 (PDT), Anabolik <bum...@gmail.com>
wrote:

>I try to read the content of file text.txt. The size of this file is
>26 Mb. And always I have the error:
>
>Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
> at java.util.Arrays.copyOf(Arrays.java:2882)
> at java.lang.AbstractStringBuilder.expandCapacity
>(AbstractStringBuilder.java:100)
> at java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:
>390)
> at java.lang.StringBuffer.append(StringBuffer.java:224)
>
>at lines contents.append(text).append(System.getProperty
>("line.separator"));
>
>How can I read and save the content of file. The content of file I
>need then in the program to show it in some dialog.

You file is too large to fit into your allocated heap. You can either
increase the heap until it is large enough to hold the entire file and
the rest of your program, or you can deal with the fine in chunks.
The size of a "chunk" is dependent on what you want to do with the
file.


>
>public static void main(String[] args) {
> File file = new File("D:\\work\\text.txt");
> StringBuffer contents = new StringBuffer();
> BufferedReader reader = null;
>
> try {
> reader = new BufferedReader(new FileReader(file));
> String text = null;
>
> // repeat until all lines is read
> while ((text = reader.readLine()) != null)
> {

All you do with the file in this example is to print it to System.out,
so rather than accumilating the whole file before printing just print
what you have and throw it away:

System.out.println(text + System.getProperty("line.separator"));

That way you have a maximum of one line in memory at one time. In
general read in the minimum amount of the file that you need to
process and when you have finished that part throw it away and read in
the next part. You are using a BufferedReader so there is no need to
do any additional file buffering - all of that is already done.

repeat
read chunk from file
process chunk
save results
until file finished

rossum

Lew

unread,
Jul 30, 2009, 8:31:52 AM7/30/09
to
Anabolik wrote:
> I try to read the content of file text.txt. The size of this file is
> 26 Mb. And always I have the error:
>
> Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
> at java.util.Arrays.copyOf(Arrays.java:2882)
> at java.lang.AbstractStringBuilder.expandCapacity
> (AbstractStringBuilder.java:100)
> at java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:
> 390)
> at java.lang.StringBuffer.append(StringBuffer.java:224)
>
> at lines contents.append(text).append(System.getProperty
> ("line.separator"));

In addition to what others have said, you can use memory more efficiently.
Preallocate the size of the 'contents' object; right now, it has to copy
itself to a larger buffer every time it grows to accomodate more text. You
know you have a 26 MB file but you initially allocate only 16 characters.

Also, use 'StringBuilder' unless you truly need the thread safety of
'StringBuffer'. It doesn't look like you do.

There are other minor ways to improve your code on which I'll comment in line.

> How can I read and save the content of file. The content of file I
> need then in the program to show it in some dialog.

You're going to show 26 MB in a dialog?

> public static void main(String[] args) {
> File file = new File("D:\\work\\text.txt");

> StringBuffer contents = new StringBuffer(); // StringBuilder
> BufferedReader reader = null;

An alternative is to initialize 'reader' in a separate 'try' block so you
don't have to check for 'null' in the later 'finally'. This is just a matter
of style.

> try {
> reader = new BufferedReader(new FileReader(file));
> String text = null;

OTOH, this 'null' initialization is truly redundant. And unnecessary.
Superfluous, even. Plus the scope of 'text' is wider than it need be.

> // repeat until all lines is read

This comment doesn't add any clarity or explanation.

> while ((text = reader.readLine()) != null)

An alternative idiom that limits the scope of 'text':

for ( String text; (text = reader.readLine()) != null; )
> {
> contents.append(text).append(System.getProperty
> ("line.separator"));

Since it's unlikely that this system property will change during the loop, you
could define a variable outside the loop to hold it.

> }
> } catch (FileNotFoundException e)
> {
> e.printStackTrace();
> } catch (IOException e)
> {
> e.printStackTrace();
> } finally
> {
> try
> {
> if (reader != null)
> {
> reader.close();
> }
> } catch (IOException e)
> {
> e.printStackTrace();
> }
> }
>
> // show file contents here
> System.out.println(contents.toString());
> }

--
Lew

RedGrittyBrick

unread,
Jul 30, 2009, 8:57:46 AM7/30/09
to

Anabolik wrote:
> I try to read the content of file text.txt. The size of this file is
> 26 Mb.

[snip: Out of Memory]

> How can I read and save the content of file. The content of file I
> need then in the program to show it in some dialog.

If the only purpose of reading this large text file is to *show* it to a
user, I'd consider reading it in chunks. Each chunk being large enough
to fill the available display space (plus some margin or factor). Then
I'd only read other chunks as needed.

I expect this isn't trivial if you want to be able to wrap lines, scroll
backwards and show scroll-bars that reflect the file size but I imagine
that the standard libraries or third-party libraries have classes that
facilitate or support this.

If the text file is strongly structured I'd consider pre-indexing it or
loading it's content into a DBMS instead.

--
RGB

Roedy Green

unread,
Jul 31, 2009, 4:31:59 PM7/31/09
to
On Thu, 30 Jul 2009 00:56:40 -0700 (PDT), Anabolik <bum...@gmail.com>
wrote, quoted or indirectly quoted someone who said :

>I try to read the content of file text.txt. The size of this file is
>26 Mb. And always I have the error:
>
>Exception in thread "main" java.lang.OutOfMemoryError

First try allocating a 100 MB byte array and see if that will fit.

If it does not, you need to either redo your code so that you allocate
nothing but one big 26 MB buffer, or process your file in chunks. You
might do that by scanning your file to find the offsets of the start
of each line, then create an index of the offsets by line number. You
can then read each line given just the line number, with
RandomAccessFile.

--
Roedy Green Canadian Mind Products
http://mindprod.com

"Patriotism is fierce as a fever, pitiless as the grave, blind as a stone, and as irrational as a headless hen."
~ Ambrose Bierce (born: 1842-06-24 died: 1914 at age: 71)

Arne Vajhøj

unread,
Aug 22, 2009, 10:30:17 PM8/22/09
to
Lew wrote:

> Anabolik wrote:
>> while ((text = reader.readLine()) != null)
>
> An alternative idiom that limits the scope of 'text':
>
> for ( String text; (text = reader.readLine()) != null; )

The while loop version is rather standard in Java for
good or for worse.

Arne

PS: I agree with all the other advice.

0 new messages