将byte []发送到服务器,outOfMemoryError

时间:2018-05-28 08:03:50

标签: android arrays sockets buffer

我正在尝试使用ssl套接字将文件(此处为视频)发送到我的服务器,我可以发送11次,但是当我再试一次时,我有一个OutOfMemoryError,我想知道如何解决这个问题。

客户端(Android):

    InputStream inputStream = null;
    try {
        inputStream = getAssets().open("test.mp4");
    } catch (IOException e) {
        e.printStackTrace();
    }

    byte[] bytes2 = null;

    try {
        bytes2 = getBytes(inputStream);
    } catch (IOException e) {
        e.printStackTrace();
    }

    if (socketConnect()) {
        try {
            Log.d("MainActivity", "Before OutputStream");
            OutputStream os = sock.getOutputStream();
            Log.d("MainActivity", "Before FileInputStream");
            Log.d("MainActivity", "Before while " + bytes2.length);
            os.write(bytes2);
            Log.d("MainActivity", "After while");
            os.flush();
            os.close();
            sock.close();
            Log.d("MainActivity", "End");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    else {
        Log.e("MainActivity", "Erreur");
    }

服务器端(Python):

import socket
import sys
import ssl


sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind(("",9999))

sock.listen(10)

i=1

while True:
    (clientsocket, (ip, port)) = sock.accept()
    connstream = ssl.wrap_socket(clientsocket,
                                 server_side = True,
                                 certfile = "server.crt",
                                 keyfile = "server.key")
    f = open('test_'+str(i)+".jpg",'wb') #open in binary
    i=i+1
    print(i)
    l = 1
    l = connstream.read(1024)

    while (l):
            print("toto")
            f.write(l)
            l = connstream.read(1024)
    f.close()

    connstream.close()

sock.close()

记录:

05-28 09:56:31.019 11519-11519/com.youstiti.simon.testenvoiwithbuffer E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.youstiti.simon.testenvoiwithbuffer, PID: 11519
java.lang.OutOfMemoryError: Failed to allocate a 33552396 byte allocation with 28973408 free bytes and 27MB until OOM
    at java.io.ByteArrayOutputStream.expand(ByteArrayOutputStream.java:91)
    at java.io.ByteArrayOutputStream.write(ByteArrayOutputStream.java:201)
    at com.youstiti.simon.testenvoiwithbuffer.MainActivity.getBytes(MainActivity.java:153)
    at com.youstiti.simon.testenvoiwithbuffer.MainActivity.onCreate(MainActivity.java:73)
    at android.app.Activity.performCreate(Activity.java:6272)
    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1107)
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2387)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2494)
    at android.app.ActivityThread.access$900(ActivityThread.java:157)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1356)
    at android.os.Handler.dispatchMessage(Handler.java:102)
    at android.os.Looper.loop(Looper.java:148)
    at android.app.ActivityThread.main(ActivityThread.java:5525)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:730)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:620)

我认为缓冲区可以解决问题,但我不知道该怎么做。

感谢您的回答

1 个答案:

答案 0 :(得分:0)

你必须按块读取和发送你的文件块以避免OOM错误,因为android堆是有限的,如下所示

if (socketConnect()) {
try {
    final int bufferSize = 8*1024;
    FileInputStream fis = new FileInputStream(/*...your file*/);
    byte[] buffer = new byte[bufferSize]; 
    int read;
    OutputStream os = sock.getOutputStream();
    while( ( read = fis.read( buffer ) ) > 0 ){
          os.write(buffer, 0, read);
    }
    os.close();
    fis.close();    
} catch (IOException e) {
    e.printStackTrace();
}
else {
    Log.e("MainActivity", "Erreur");
}

通过添加android:largeHeap="true"来避免请求大堆,谷歌说:

  

永远不要因为你的内存不足而请求大堆   你需要快速修复

请查看the doc了解更多