读取大型文本文件时出现OutOfMemoryError

时间:2013-11-30 23:48:16

标签: android memory-leaks arraylist android-asynctask out-of-memory

我的应用程序具有从SD卡读取文本文件的功能,当我读取小文件没有问题时,但是当我读取文本文件太大时,我得到一个OutOfMemoryError。阅读类似的问题会改变我的文本,现在使用AsyncTask来读取文件,但即便如此,我也会遇到同样的错误。

这是我的代码:

 private class MiTarea extends AsyncTask<String, Integer, String > {

    protected void onPreExecute() {
        dialog.setProgress(0);
        dialog.setMax(100);
        dialog.show(); //Mostramos el diálogo antes de comenzar
    }

    protected String doInBackground(String... urls) {


                    if (carpeta_para_leer == "Textos"){
                        sdcard = new File( Environment.getExternalStorageDirectory().toString()+"/" + carpeta_para_leer + "/");
                    }else{
                        sdcard = new File( Environment.getExternalStorageDirectory().toString()+"/Textos/" + carpeta_para_leer + "/");
                    }


                    //Get the text file
                    File file = new File(sdcard, nombre_texto + ".txt");
                    sizeInBytes = file.length();
                    currentBytes = 0;

                    //Read text from file
                    StringBuilder text = new StringBuilder();
                    nepe = new ArrayList<String>();


                    try {
                        BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(file), "Cp1252"));
                        String line;

                        while ((line = br.readLine()) != null) {
                            line.replaceAll("\t", " ");
                            line.replaceAll("\n", " ");
                            delimitadores = " ";
                            String[] hola = line.split(delimitadores);
                            for (int i = 0; i < hola.length; i++ ){
                                nepe.add(hola[i]);
                            }
                            currentBytes += (long)line.length(); //HERE I TRY TO UPDATE THE PROGRESSBAR
                            por =  (currentBytes * 50) / sizeInBytes;
                            publishProgress(porcent);
                            Log.d("DoINBackGround", "" + currentBytes + " Y EL TOTAL ES " + sizeInBytes);
                        }
                    }
                    catch (IOException e) {

                    }

                    Holmes1 =text.toString();
                   // delimitadores = " ";
                   // arrayHolmes1 = Holmes1.split(delimitadores);

        return Holmes1;
    }

    protected void onProgressUpdate (Integer... valores) {
        dialog.setProgress((int) ((int) (currentBytes * 100) / sizeInBytes));
        Log.d("LLAMADA A PROGRESSBAR", "TOTAL: " + sizeInBytes + " LLEVAS: " + currentBytes + " PORCENTAJE: " + currentBytes/sizeInBytes + " POR: " + por );
        if (dialog.getProgress() == 100){
            onPostExecute(1);
        }
    }

    protected void onPostExecute(Integer bytes) {
        dialog.dismiss();
    }
}

这就是logcat:

11-30 17:21:45.332    6175-6324/ccv.checkhellsing.lecturarapida E/dalvikvm-heap﹕ Out of memory on a 1787236-byte allocation.
11-30 17:21:45.449    6175-6324/ccv.checkhellsing.lecturarapida E/AndroidRuntime﹕ FATAL EXCEPTION: AsyncTask #1
    java.lang.RuntimeException: An error occured while executing doInBackground()
            at android.os.AsyncTask$3.done(AsyncTask.java:200)
            at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:274)
            at java.util.concurrent.FutureTask.setException(FutureTask.java:125)
            at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:308)
            at java.util.concurrent.FutureTask.run(FutureTask.java:138)
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1088)
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:581)
            at java.lang.Thread.run(Thread.java:1019)
     Caused by: java.lang.OutOfMemoryError
            at java.util.ArrayList.add(ArrayList.java:123)
            at ccv.checkhellsing.lecturarapida.EL_Entrenamiento$MiTarea.doInBackground(EL_Entrenamiento.java:1262)
            at ccv.checkhellsing.lecturarapida.EL_Entrenamiento$MiTarea.doInBackground(EL_Entrenamiento.java:1224)
            at android.os.AsyncTask$2.call(AsyncTask.java:185)
            at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:306)
            at java.util.concurrent.FutureTask.run(FutureTask.java:138)
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1088)
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:581)
            at java.lang.Thread.run(Thread.java:1019)
11-30 17:21:45.925    6175-6175/ccv.checkhellsing.lecturarapida E/WindowManager﹕ Activity ccv.checkhellsing.lecturarapida.EL_Entrenamiento has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@405b43e0 that was originally added here
    android.view.WindowLeaked: Activity ccv.checkhellsing.lecturarapida.EL_Entrenamiento has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@405b43e0 that was originally added here
            at android.view.ViewRoot.<init>(ViewRoot.java:258)
            at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:148)
            at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:91)
            at android.view.Window$LocalWindowManager.addView(Window.java:424)
            at android.app.Dialog.show(Dialog.java:241)
            at ccv.checkhellsing.lecturarapida.EL_Entrenamiento$MiTarea.onPreExecute(EL_Entrenamiento.java:1229)
            at android.os.AsyncTask.execute(AsyncTask.java:391)
            at ccv.checkhellsing.lecturarapida.EL_Entrenamiento.onClick(EL_Entrenamiento.java:497)
            at android.view.View.performClick(View.java:2485)
            at android.view.View$PerformClick.run(View.java:9081)
            at android.os.Handler.handleCallback(Handler.java:587)
            at android.os.Handler.dispatchMessage(Handler.java:92)
            at android.os.Looper.loop(Looper.java:123)
            at android.app.ActivityThread.main(ActivityThread.java:3683)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:507)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
            at com.android.internal.os.ZygoteInit.main(Native Method)
            at dalvik.system.NativeStart.main(Native Method)
11-30 17:21:53.386    6325-6334/? E/CursorWindow﹕ need to grow: mSize = 1048576, size = 119, freeSpace() = 81, numRows = 4188
11-30 17:21:53.386    6325-6334/? E/CursorWindow﹕ not growing since there are already 4188 row(s), max size 1048576
11-30 17:21:53.386    6325-6334/? E/Cursor﹕ Failed allocating 119 bytes for text/blob at 4187,3
11-30 17:22:59.246    6325-6334/? E/CursorWindow﹕ need to grow: mSize = 1048576, size = 119, freeSpace() = 81, numRows = 4188
11-30 17:22:59.246    6325-6334/? E/CursorWindow﹕ not growing since there are already 4188 row(s), max size 1048576
11-30 17:22:59.246    6325-6334/? E/Cursor﹕ Failed allocating 119 bytes for text/blob at 4187,3
11-30 17:24:03.941    6325-6331/? E/CursorWindow﹕ need to grow: mSize = 1048576, size = 119, freeSpace() = 81, numRows = 4188
11-30 17:24:03.941    6325-6331/? E/CursorWindow﹕ not growing since there are already 4188 row(s), max size 1048576
11-30 17:24:03.941    6325-6331/? E/Cursor﹕ Failed allocating 119 bytes for text/blob at 4187,3
11-30 17:24:53.450    1255-6344/? E/GTalkService﹕ createConnection: missing account.authToken...
11-30 17:24:57.638    6402-6402/? E/dalvikvm﹕ Could not find class 'android.database.sqlite.SQLiteCantOpenDatabaseException', referenced from method com.google.android.gms.plus.provider.PlusProvider.a
11-30 17:24:57.865    6325-6330/? E/CursorWindow﹕ need to grow: mSize = 1048576, size = 119, freeSpace() = 81, numRows = 4188
11-30 17:24:57.865    6325-6330/? E/CursorWindow﹕ not growing since there are already 4188 row(s), max size 1048576
11-30 17:24:57.865    6325-6330/? E/Cursor﹕ Failed allocating 119 bytes for text/blob at 4187,3
11-30 17:25:03.372    1255-6412/? E/GTalkService﹕ createConnection: missing account.authToken...
11-30 17:25:04.474    6402-6415/? E/dalvikvm﹕ Could not find class 'android.app.AppOpsManager', referenced from method axo.a
11-30 17:25:05.216    6325-6334/? E/CursorWindow﹕ need to grow: mSize = 1048576, size = 119, freeSpace() = 81, numRows = 4188
11-30 17:25:05.224    6325-6334/? E/CursorWindow﹕ not growing since there are already 4188 row(s), max size 1048576
11-30 17:25:05.224    6325-6334/? E/Cursor﹕ Failed allocating 119 bytes for text/blob at 4187,3
11-30 17:26:11.779    6325-6331/? E/CursorWindow﹕ need to grow: mSize = 1048576, size = 119, freeSpace() = 81, numRows = 4188
11-30 17:26:11.779    6325-6331/? E/CursorWindow﹕ not growing since there are already 4188 row(s), max size 1048576
11-30 17:26:11.779    6325-6331/? E/Cursor﹕ Failed allocating 119 bytes for text/blob at 4187,3
11-30 17:27:17.700    6325-6331/? E/CursorWindow﹕ need to grow: mSize = 1048576, size = 119, freeSpace() = 81, numRows = 4188
11-30 17:27:17.700    6325-6331/? E/CursorWindow﹕ not growing since there are already 4188 row(s), max size 1048576
11-30 17:27:17.700    6325-6331/? E/Cursor﹕ Failed allocating 119 bytes for text/blob at 4187,3
11-30 17:28:22.638    6325-6334/? E/CursorWindow﹕ need to grow: mSize = 1048576, size = 119, freeSpace() = 81, numRows = 4188
11-30 17:28:22.638    6325-6334/? E/CursorWindow﹕ not growing since there are already 4188 row(s), max size 1048576
11-30 17:28:22.638    6325-6334/? E/Cursor﹕ Failed allocating 119 bytes for text/blob at 4187,3
11-30 17:29:27.544    6325-6334/? E/CursorWindow﹕ need to grow: mSize = 1048576, size = 119, freeSpace() = 81, numRows = 4188
11-30 17:29:27.544    6325-6334/? E/CursorWindow﹕ not growing since there are already 4188 row(s), max size 1048576
11-30 17:29:27.544    6325-6334/? E/Cursor﹕ Failed allocating 119 bytes for text/blob at 4187,3
11-30 17:30:31.990    6325-6331/? E/CursorWindow﹕ need to grow: mSize = 1048576, size = 119, freeSpace() = 81, numRows = 4188
11-30 17:30:31.990    6325-6331/? E/CursorWindow﹕ not growing since there are already 4188 row(s), max size 1048576
11-30 17:30:31.997    6325-6331/? E/Cursor﹕ Failed allocating 119 bytes for text/blob at 4187,3
11-30 17:31:37.779    6325-6331/? E/CursorWindow﹕ need to grow: mSize = 1048576, size = 119, freeSpace() = 81, numRows = 4188
11-30 17:31:37.786    6325-6331/? E/CursorWindow﹕ not growing since there are already 4188 row(s), max size 1048576
11-30 17:31:37.786    6325-6331/? E/Cursor﹕ Failed allocating 119 bytes for text/blob at 4187,3
11-30 17:32:01.146    1114-1142/? E/ResourceType﹕ Style contains key with bad entry: 0x010102f0
11-30 17:32:03.443    6540-6540/ccv.checkhellsing.lecturarapida E/ResourceType﹕ Style contains key with bad entry: 0x010102f0
11-30 17:32:08.341    6540-6540/ccv.checkhellsing.lecturarapida E/ResourceType﹕ Style contains key with bad entry: 0x010102f0
11-30 17:32:08.982    6402-6543/? E/dalvikvm﹕ Could not find class 'android.os.UserManager', referenced from method aod.b
11-30 17:32:08.982    6402-6543/? E/dalvikvm﹕ Could not find class 'android.os.UserManager', referenced from method aod.c
11-30 17:32:08.990    6402-6543/? E/dalvikvm﹕ Could not find class 'android.os.UserManager', referenced from method aod.d
11-30 17:32:49.732    6657-6662/? E/CursorWindow﹕ need to grow: mSize = 1048576, size = 119, freeSpace() = 81, numRows = 4188
11-30 17:32:49.732    6657-6662/? E/CursorWindow﹕ not growing since there are already 4188 row(s), max size 1048576
11-30 17:32:49.732    6657-6662/? E/Cursor﹕ Failed allocating 119 bytes for text/blob at 4187,3
11-30 17:33:56.411    6657-6662/? E/CursorWindow﹕ need to grow: mSize = 1048576, size = 119, freeSpace() = 81, numRows = 4188
11-30 17:33:56.411    6657-6662/? E/CursorWindow﹕ not growing since there are already 4188 row(s), max size 1048576
11-30 17:33:56.411    6657-6662/? E/Cursor﹕ Failed allocating 119 bytes for text/blob at 4187,3
11-30 17:35:01.396    6657-6662/? E/CursorWindow﹕ need to grow: mSize = 1048576, size = 119, freeSpace() = 81, numRows = 4188
11-30 17:35:01.404    6657-6662/? E/CursorWindow﹕ not growing since there are already 4188 row(s), max size 1048576
11-30 17:35:01.404    6657-6662/? E/Cursor﹕ Failed allocating 119 bytes for text/blob at 4187,3
11-30 17:36:05.716    6657-6663/? E/CursorWindow﹕ need to grow: mSize = 1048576, size = 119, freeSpace() = 81, numRows = 4188
11-30 17:36:05.716    6657-6663/? E/CursorWindow﹕ not growing since there are already 4188 row(s), max size 1048576
11-30 17:36:05.716    6657-6663/? E/Cursor﹕ Failed allocating 119 bytes for text/blob at 4187,3
11-30 17:37:10.021    6657-6663/? E/CursorWindow﹕ need to grow: mSize = 1048576, size = 119, freeSpace() = 81, numRows = 4188
11-30 17:37:10.021    6657-6663/? E/CursorWindow﹕ not growing since there are already 4188 row(s), max size 1048576
11-30 17:37:10.021    6657-6663/? E/Cursor﹕ Failed allocating 119 bytes for text/blob at 4187,3
11-30 17:38:14.255    6657-6662/? E/CursorWindow﹕ need to grow: mSize = 1048576, size = 119, freeSpace() = 81, numRows = 4188
11-30 17:38:14.255    6657-6662/? E/CursorWindow﹕ not growing since there are already 4188 row(s), max size 1048576
11-30 17:38:14.255    6657-6662/? E/Cursor﹕ Failed allocating 119 bytes for text/blob at 4187,3
11-30 17:39:18.544    6657-6662/? E/CursorWindow﹕ need to grow: mSize = 1048576, size = 119, freeSpace() = 81, numRows = 4188
11-30 17:39:18.544    6657-6662/? E/CursorWindow﹕ not growing since there are already 4188 row(s), max size 1048576
11-30 17:39:18.544    6657-6662/? E/Cursor﹕ Failed allocating 119 bytes for text/blob at 4187,3
11-30 17:40:22.810    6657-6663/? E/CursorWindow﹕ need to grow: mSize = 1048576, size = 119, freeSpace() = 81, numRows = 4188
11-30 17:40:22.810    6657-6663/? E/CursorWindow﹕ not growing since there are already 4188 row(s), max size 1048576
11-30 17:40:22.810    6657-6663/? E/Cursor﹕ Failed allocating 119 bytes for text/blob at 4187,3
11-30 17:41:27.094    6657-6662/? E/CursorWindow﹕ need to grow: mSize = 1048576, size = 119, freeSpace() = 81, numRows = 4188
11-30 17:41:27.094    6657-6662/? E/CursorWindow﹕ not growing since there are already 4188 row(s), max size 1048576
11-30 17:41:27.094    6657-6662/? E/Cursor﹕ Failed allocating 119 bytes for text/blob at 4187,3
11-30 17:41:48.555    1255-6677/? E/GTalkService﹕ createConnection: missing account.authToken...
11-30 17:41:52.766    6657-6663/? E/CursorWindow﹕ need to grow: mSize = 1048576, size = 119, freeSpace() = 81, numRows = 4188
11-30 17:41:52.766    6657-6663/? E/CursorWindow﹕ not growing since there are already 4188 row(s), max size 1048576
11-30 17:41:52.766    6657-6663/? E/Cursor﹕ Failed allocating 119 bytes for text/blob at 4187,3
11-30 17:41:53.180    1255-6735/? E/GTalkService﹕ createConnection: missing account.authToken...
11-30 17:42:02.281    6657-6663/? E/CursorWindow﹕ need to grow: mSize = 1048576, size = 119, freeSpace() = 81, numRows = 4188
11-30 17:42:02.289    6657-6663/? E/CursorWindow﹕ not growing since there are already 4188 row(s), max size 1048576
11-30 17:42:02.289    6657-6663/? E/Cursor﹕ Failed allocating 119 bytes for text/blob at 4187,3
11-30 17:43:10.281    6657-6663/? E/CursorWindow﹕ need to grow: mSize = 1048576, size = 119, freeSpace() = 81, numRows = 4188
11-30 17:43:10.281    6657-6663/? E/CursorWindow﹕ not growing since there are already 4188 row(s), max size 1048576
11-30 17:43:10.281    6657-6663/? E/Cursor﹕ Failed allocating 119 bytes for text/blob at 4187,3
11-30 17:44:16.438    6657-6662/? E/CursorWindow﹕ need to grow: mSize = 1048576, size = 119, freeSpace() = 81, numRows = 4188
11-30 17:44:16.438    6657-6662/? E/CursorWindow﹕ not growing since there are already 4188 row(s), max size 1048576
11-30 17:44:16.438    6657-6662/? E/Cursor﹕ Failed allocating 119 bytes for text/blob at 4187,3

我该如何解决?

1 个答案:

答案 0 :(得分:0)

您正在使用已经逐字节读取文件的InputStreamReader类。问题是由不能支持bug文件大小的BufferedReader引起的。

尝试使用setChunkedStreamingMode(1024)将数据块化为特定大小,这样就不需要将整个文件保留在内存中。

了解更多详情:Upload large file in Android without outofmemory error

祝你好运。