在android中处理大文件的最佳方法

时间:2017-08-18 12:21:07

标签: android arrays base64

我正在尝试从本地文件夹中获取'pdf'文件并将其转换为字节数组,如下所示。由于pdf很大,它会引发“内存不足异常”

所以我想克服这个问题,因为我的用户将上传超过10-20 MB文件的文件。

将文件转换为字节数组:

public static String convertFileToByteArray(File f) {
        byte[] byteArray = null;
        try {
            InputStream inputStream = new FileInputStream(f);
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            byte[] b = new byte[1024 * 11];
            int bytesRead = 0;

            while ((bytesRead = inputStream.read(b)) != -1) {
                bos.write(b, 0, bytesRead);
            }

            byteArray = bos.toByteArray();

            Log.e("Byte array", ">" + byteArray);

        } catch (IOException e) {
            e.printStackTrace();
        }
        return Base64.encodeToString(byteArray, Base64.NO_WRAP);
    }

发生异常:

java.lang.OutOfMemoryError
at java.io.ByteArrayOutputStream.expand(ByteArrayOutputStream.java:91)
at java.io.ByteArrayOutputStream.write(ByteArrayOutputStream.java:201)
at android.util.Base64OutputStream.internalWrite(Base64OutputStream.java:141)
at android.util.Base64OutputStream.write(Base64OutputStream.java:101)
at com.sampleapp.testapp.testapp.MainActivity.convertFileToByteArray(MainActivity.java:547)
at com.sampleapp.testapp.testapp.MainActivity.onActivityResult(MainActivity.java:401)
at android.app.Activity.dispatchActivityResult(Activity.java:5643)
at android.app.ActivityThread.deliverResults(ActivityThread.java:3677)
at android.app.ActivityThread.handleSendResult(ActivityThread.java:3724)
at android.app.ActivityThread.access$1400(ActivityThread.java:175)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1356)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:146)
at android.app.ActivityThread.main(ActivityThread.java:5602)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1283)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1099)
at dalvik.system.NativeStart.main(Native Method)

2 个答案:

答案 0 :(得分:1)

解决方案是同时拥有两个流,一个读取内存,另一个发送到服务器。您将一大块数据读取到中间缓冲区(例如4096字节)并发送,然后使用此单个小缓冲区重复。

另外,我建议使用某种类型的库来做,比如着名的Retrofit github.com/square/retrofit

关于如何在博客中使用它有plenty of examples,教程... This tutorial看起来非常好,并且目标是Retrofit 2.x。

答案 1 :(得分:-1)

您可以在AndroidManifest.xml中为您的应用程序使用android:largeHeap让系统知道您需要更多内存。检查here

但是我建议你不要把整个文件加载到内存中,考虑分页或者那样的想法。