3

I am reading a text file from the SD card. My code works if the file size is small, but when files are larger than 4 or 5 mb, it gives me an error.

Here is the code that I used:

File myFile = new File(""+listAllSdCardFile.get(filePostion));
BufferedReader br1 = new BufferedReader( new FileReader( myFile ) );
StringBuffer text = new StringBuffer();
for(String line; (line=br1.readLine())!=null;)
{
    text.append( line );
}
line=text.toString();

This is the error that I get:

02-05 07:12:55.184: E/AndroidRuntime(778): FATAL EXCEPTION: Background
02-05 07:12:55.184: E/AndroidRuntime(778): java.lang.OutOfMemoryError
02-05 07:12:55.184: E/AndroidRuntime(778):  at java.lang.AbstractStringBuilder.enlargeBuffer(AbstractStringBuilder.java:97)
02-05 07:12:55.184: E/AndroidRuntime(778):  at java.lang.AbstractStringBuilder.append0(AbstractStringBuilder.java:157)
02-05 07:12:55.184: E/AndroidRuntime(778):  at java.lang.StringBuffer.append(StringBuffer.java:215)
02-05 07:12:55.184: E/AndroidRuntime(778):  at com.reader.fastreader.TextReader.StringSpilitFunction(TextReader.java:344)
02-05 07:12:55.184: E/AndroidRuntime(778):  at com.reader.fastreader.TextReader$3$1$1.run(TextReader.java:134)
02-05 07:12:55.184: E/AndroidRuntime(778):  at java.lang.Thread.run(Thread.java:1096)
02-05 07:12:55.784: E/WindowManager(778): Activity com.reader.fastreader.TextReader has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@44f74708 that was originally added here
02-05 07:12:55.784: E/WindowManager(778): android.view.WindowLeaked: Activity com.reader.fastreader.TextReader has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@44f74708 that was originally added here
02-05 07:12:55.784: E/WindowManager(778):   at android.view.ViewRoot.<init>(ViewRoot.java:247)
02-05 07:12:55.784: E/WindowManager(778):   at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:148)
02-05 07:12:55.784: E/WindowManager(778):   at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:91)
02-05 07:12:55.784: E/WindowManager(778):   at android.view.Window$LocalWindowManager.addView(Window.java:424)
02-05 07:12:55.784: E/WindowManager(778):   at android.app.Dialog.show(Dialog.java:241)
02-05 07:12:55.784: E/WindowManager(778):   at com.reader.fastreader.TextReader$3$1.onItemClick(TextReader.java:140)
02-05 07:12:55.784: E/WindowManager(778):   at android.widget.AdapterView.performItemClick(AdapterView.java:284)
02-05 07:12:55.784: E/WindowManager(778):   at android.widget.ListView.performItemClick(ListView.java:3382)
02-05 07:12:55.784: E/WindowManager(778):   at android.widget.AbsListView$PerformClick.run(AbsListView.java:1696)
02-05 07:12:55.784: E/WindowManager(778):   at android.os.Handler.handleCallback(Handler.java:587)
02-05 07:12:55.784: E/WindowManager(778):   at android.os.Handler.dispatchMessage(Handler.java:92)
02-05 07:12:55.784: E/WindowManager(778):   at android.os.Looper.loop(Looper.java:123)
02-05 07:12:55.784: E/WindowManager(778):   at android.app.ActivityThread.main(ActivityThread.java:4627)
02-05 07:12:55.784: E/WindowManager(778):   at java.lang.reflect.Method.invokeNative(Native Method)
02-05 07:12:55.784: E/WindowManager(778):   at java.lang.reflect.Method.invoke(Method.java:521)
02-05 07:12:55.784: E/WindowManager(778):   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
02-05 07:12:55.784: E/WindowManager(778):   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
02-05 07:12:55.784: E/WindowManager(778):   at dalvik.system.NativeStart.main(Native Method)

What is wrong with my code?

abierto
  • 1,447
  • 7
  • 29
  • 57

2 Answers2

1

It's not about file reading. You are out of memory because your string is very large and you can't store it in memory. Try to free memory (delete some unused data, 5 it's not too much) or change program structure.

Leonidos
  • 10,482
  • 2
  • 28
  • 37
  • 1
    There is no magic button "free memory". It's your program. Your were given at least 16Mb of heap to store your data when your program started. Dont waste it. Why do you need to keep whole string in memory? – Leonidos Feb 05 '13 at 07:40
  • @Leonldos i had removed it now i am storing that sting into arraylist but yet same problem arrise. –  Feb 05 '13 at 07:51
  • Your data has same memory footprint. – Leonidos Feb 05 '13 at 07:57
  • @Leonidos, i have the similar problem while reading file from sdcard, File(6 to 7MB) contain jsonArray, i was reading that file contains into stringbuffer- parse it- insert into DB. Is there any other way to read file having JsonArray and stored into DBb? – Hiren Dabhi Oct 04 '13 at 13:49
  • Why dont you use google? Some JSON libs supports streaming. Or you can split big file to some small ones and parce them sequentially. http://stackoverflow.com/questions/9390368/java-best-approach-to-parse-huge-extra-large-json-file – Leonidos Oct 05 '13 at 05:26
1

You are simply out of memory, file is read properly. As said, first option is to see where you can free some kB of heap space in your app. However, if you got a slightly bigger file, it might break the same way again.

You need to answer that question: why do I need the whole text at once in memory? And unless you find a definitive point to do so, you will need to answer the following question: how will I make my algorithm/processing/display of the file in chunks so that I only need to hold in memory a piece of the file.

With some more info about what you need to do with that text, you will get some more input about how to do it another way if you need.


Edit:

instead of displaying the whole file content at once in the edit text, you could for instance show pages: read a part of the file (say for example 100 lines). Once the user reaches the bottom of the current page, load the next 100 lines from the file (and of course, discard the previous 100).

You could do this nicely with a ViewPager (each fragment shows 100 lines, swipe to the left to show next page of text, ...)

The first time, you might want to go throught the whole file in order to count the total number of lines (without storing the text) and thus be able to indicate how many pages that would do.

Vincent Mimoun-Prat
  • 28,208
  • 16
  • 81
  • 124
  • i want to read file and display on textview and as per string containing out of memory i had change code now i am storing line value in array list but yet i cause problem in arraylist. –  Feb 05 '13 at 07:54
  • See edited answer. Reading the whole text is not a good idea and not necessary (the person reading never sees the whole text at once). – Vincent Mimoun-Prat Feb 05 '13 at 07:58
  • By the way, storing the whole file in an array, an ArrayList, a String, a StringBuffer, a Map or a bag will always lead to OutOfMemory. – Vincent Mimoun-Prat Feb 05 '13 at 08:00
  • read it the same way, but only store the lines you need to display (not the whole file). – Vincent Mimoun-Prat Feb 05 '13 at 09:24