Вопрос

I have a big problem, that I am reading 2^21 bytes from a video file which resides in Sdcard but when we write the same in ByteArrayOutputStream it throws an Exception as Out of Memory. I don't know why? Please suggest the right solution for the same.

Here is the stack trace.

Error Stack:

11-03 19:24:23.193: ERROR/AndroidRuntime(28258): FATAL EXCEPTION: main
11-03 19:24:23.193: ERROR/AndroidRuntime(28258): java.lang.OutOfMemoryError
11-03 19:24:23.193: ERROR/AndroidRuntime(28258):     at java.io.ByteArrayOutputStream.expand(ByteArrayOutputStream.java:93)
11-03 19:24:23.193: ERROR/AndroidRuntime(28258):     at java.io.ByteArrayOutputStream.write(ByteArrayOutputStream.java:218)
11-03 19:24:23.193: ERROR/AndroidRuntime(28258):     at com.example.TestCryptoActivity.onCreate(TestCryptoActivity.java:42)
11-03 19:24:23.193: ERROR/AndroidRuntime(28258):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
11-03 19:24:23.193: ERROR/AndroidRuntime(28258):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2627)
11-03 19:24:23.193: ERROR/AndroidRuntime(28258):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679)
11-03 19:24:23.193: ERROR/AndroidRuntime(28258):     at android.app.ActivityThread.access$2300(ActivityThread.java:125)
11-03 19:24:23.193: ERROR/AndroidRuntime(28258):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2033)
11-03 19:24:23.193: ERROR/AndroidRuntime(28258):     at android.os.Handler.dispatchMessage(Handler.java:99)
11-03 19:24:23.193: ERROR/AndroidRuntime(28258):     at android.os.Looper.loop(Looper.java:123)
11-03 19:24:23.193: ERROR/AndroidRuntime(28258):     at android.app.ActivityThread.main(ActivityThread.java:4627)
11-03 19:24:23.193: ERROR/AndroidRuntime(28258):     at java.lang.reflect.Method.invokeNative(Native Method)
11-03 19:24:23.193: ERROR/AndroidRuntime(28258):     at java.lang.reflect.Method.invoke(Method.java:521)
11-03 19:24:23.193: ERROR/AndroidRuntime(28258):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
11-03 19:24:23.193: ERROR/AndroidRuntime(28258):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
11-03 19:24:23.193: ERROR/AndroidRuntime(28258):     at dalvik.system.NativeStart.main(Native Method)

Code:

try {
    is = new FileInputStream("/sdcard/E0022505.mp4");
} catch (FileNotFoundException e2) {
    // TODO Auto-generated catch block
    e2.printStackTrace();
}

ByteArrayOutputStream bos = new ByteArrayOutputStream();
byte[] b = new byte[1024];
try {
    while ((bytesRead  = is.read(b)) != -1) {
        bos.write(b, 0, bytesRead);//--------This position returns the same error
    }
} catch (IOException e1) {
    // TODO Auto-generated catch block
    e1.printStackTrace();
}

byte[] bytes = bos.toByteArray();
try {
    String byteString = new String(bytes,"UTF-8");
    System.out.println("the bytes array of video:"+byteString);
} catch (UnsupportedEncodingException e1) {
    // TODO Auto-generated catch block
    e1.printStackTrace();
}
Это было полезно?

Решение

What you are doing isn't practical, but the way to do it is as follows:

File file = new File("/sdcard/E0022505.mp4");
try {
       is = new FileInputStream(file);
} catch (FileNotFoundException e2) {
       e2.printStackTrace();
}
byte[] fileData = new byte[file.length()];
int read = 0;
while(read != fileData.length) {
   read += is.read(fileData, read, fileData.length - read);
}
//fileData now has all of the files bytes (don't forget to close is)

Другие советы

If you know how big your file is going to be, you'd probably want to seed the bytearrayoutputstream to that size (or slightly larger) in the constructor. I'm not 100% sure of the details, but I think BAOS creates a new array, and copies the old one in, each time 'expand' is called. Other implementations keep a list of arrays that are rebuilt when outputting. Either way, you don't want that (doubles memory usage, or worse).

new ByteArrayOutputStream(new File(Environment.getExternalStorageDirectory(), "E0022505.mp4").length());
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top