如何为Android中的套接字上接收的文件分配20 MB

时间:2017-08-10 17:36:41

标签: android sockets file-transfer

我不断收到“内存不足”的问题。我看到很多线程,我明白Android OS会限制主要的内存块。但是这些文件共享应用程序如何工作?

我的代码适用于低于10 MB,但对于10-15 MB,它有时可以工作,有时不工作,对于15 MB +它永远不会工作。

这里我试图分配大约11 MB,有时也失败了。

我在Manifest中尝试了android:largeHeap =“true”。没有帮助。

实际上,我必须转移一些已经压缩过的视频。有什么建议吗?

我的代码段:

 public class FileTxThread extends Thread {
        private  ServerSocket serverSocket;
        private  Socket clientSocket;
        private InputStream inputStream;
        private FileOutputStream fileOutputStream;
        private BufferedOutputStream bufferedOutputStream;
        private  int filesize = 11728640; // filesize temporary hardcoded
        private  int bytesRead;
        private  int current = 0;
        Socket socket;

        FileTxThread(Socket socket){
            this.socket= socket;
            Log.d("naval", "constructor file thread initialized");
        }

        @Override
        public void run() {

            Log.d("lvmh", "Run function  file thread");
            byte[] mybytearray = new byte[filesize];    //create byte array to buffer the file
            try {
                inputStream = socket.getInputStream();


                // check for SD card mounted
                if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState()))
                {
                    Log.d("naval", "Mounted");
                }

                bufferedOutputStream = new BufferedOutputStream(fileOutputStream);
                Log.d("lvmh","Rceiving setting path"+imageCount);



                //System.out.println("Receiving...");


                //following lines read the input slide file byte by byte
                bytesRead = inputStream.read(mybytearray, 0, mybytearray.length);
                current = bytesRead;

                do {
                    bytesRead = inputStream.read(mybytearray, current, (mybytearray.length - current));
                    if (bytesRead >= 0) {
                        current += bytesRead;
                    }
                } while (bytesRead > -1);
                Log.d("lvmh", ">>>>>Receiving" + bytesRead);
                Log.d("lvmh",">>>>>navalllllllllll bytes read - "+current);
                bytesRead = 0; //reset


                try {
                    if(current>20)
                    {
                        fileOutputStream = new FileOutputStream(Environment.getExternalStorageDirectory() + "/lvmh/"+imageCount+"img.mp4");
                        videoflag = true;
                        Log.d("lvmh","Mp4 received in bytes- "+current);
                    }
                    else{
                        fileOutputStream = new FileOutputStream(Environment.getExternalStorageDirectory() + "/lvmh/" +imageCount+"img.jpg");
                        Log.d("lvmh","Image received in bytes- "+current);
                    }

                }catch (IOException e)
                {
                    e.printStackTrace();
                }

                bufferedOutputStream = new BufferedOutputStream(fileOutputStream);
                Log.d("LVMH","Rceiving setting path"+imageCount);


                bufferedOutputStream.write(mybytearray, 0, current);

1 个答案:

答案 0 :(得分:-1)

socket.setReceiveBufferSize(11728640); //11.72864 MB - 这就是为什么有时你在10-15 MB失败的原因

因为,你不需要知道这里的impl,只需拨打socket.setReceiveBufferSize(11728640);,它就能解决你的问题。 impl是LocalSocketImpl类(link)的实例。但是,如果你想了解更多, setReceiveBufferSize()的实现如下:

public void setReceiveBufferSize(int size) throws IOException 
    {
        impl.setOption(SocketOptions.SO_RCVBUF, Integer.valueOf(size));
    }

了解更多:https://alvinalexander.com/java/jwarehouse/android/core/java/android/net/LocalSocket.java.shtml

当你调用setReceiveBufferSize()时,当使用setsockopt(2)设置时,内核会将此值加倍(以便为簿记开销留出空间),并且getsockopt(2)返回此doubled值。请参见链接:http://man7.org/linux/man-pages/man7/socket.7.html

现在,您的套接字有一个11728640 KB的双倍大小的缓冲区。你不应该得到“内存不足”的问题。

请注意 堆空间套接字无关。 套接字缓冲区相关。

默认尺寸为IS 4K。您可以在此处找到此信息。 https://developer.android.com/reference/java/net/SocketOptions.html#SO_RCVBUF

SO_RCVBUF常量是相应地提示操作系统更改ReceiveBuffer大小。