5

I am trying to read a text file and create a string. I am using following code:

 String FILENAME = "file.txt";
 File file = getApplicationContext().getFileStreamPath(FILENAME);

 int size = (int) file.length();
 System.out.println("size: "+size);
 byte[] bytes = new byte[size];

 BufferedInputStream buf = new BufferedInputStream(new FileInputStream(file));
 buf.read(bytes, 0, bytes.length);
 buf.close();

 System.out.println("buf string: "+new String(bytes));

size in this case is 5295164. in the last line of code, i get following exception:

 FATAL EXCEPTION: main
 java.lang.OutOfMemoryError
     at java.lang.AbstractStringBuilder.enlargeBuffer(AbstractStringBuilder.java:94)
     at java.lang.AbstractStringBuilder.append0(AbstractStringBuilder.java:145)
     at java.lang.StringBuilder.append(StringBuilder.java:216)
     at se.egretails.ssapp.MyActivity$4.onClick(MyActivity.java:461)
     at android.view.View.performClick(View.java:4084)
     at android.view.View$PerformClick.run(View.java:16966)
     at android.os.Handler.handleCallback(Handler.java:615)
     at android.os.Handler.dispatchMessage(Handler.java:92)
     at android.os.Looper.loop(Looper.java:137)
     at android.app.ActivityThread.main(ActivityThread.java:4812)
     at java.lang.reflect.Method.invokeNative(Native Method)
     at java.lang.reflect.Method.invoke(Method.java:511)
     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
     at dalvik.system.NativeStart.main(Native Method)

How should i solve this? Thanks in advance.

Piscean
  • 3,069
  • 12
  • 47
  • 96
  • 4
    There are various problems here: 1) You're not closing your stream if an exception is thrown; 2) You're using the default character encoding, which is usually the wrong choice; 3) You're *assuming* that `InputStream.read` will read the whole of your file in one go; 4) We have no idea how big your file is. – Jon Skeet Feb 24 '14 at 10:27
  • 5
    Android apps have a memory limit of 16MB each. Your file is 5.04MB. Your String is 10.08MB if the file contains ASCII text. That leaves 0.88MB for everything else. Chances are, everything else is bigger than that. Rethink your approach. – user253751 Feb 24 '14 at 10:29

1 Answers1

4

The buffer is too large. Try this:

    InputStream content = new FileInputStream(file);

    int numRead;
    final int bufferSize = 1024;
    byte[] buffer = new byte[bufferSize];
    ByteArrayOutputStream outString = new ByteArrayOutputStream();
    try{
        while ((numRead = content.read(buffer)) != -1) {
            outString.write(buffer, 0, numRead);
        }
    } finally {
        content.close();
    }
    return new String(outString.toByteArray());
Manuel Spigolon
  • 11,003
  • 5
  • 50
  • 73