如何为 Android 套接字上接收到的文件分配 20 MB
How to allocate 20 MB for file received on socket in Android
我不断收到 "out of memory" 问题。我看到很多线程,我明白 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);
socket.setReceiveBufferSize(11728640);
//11.72864 MB -- 这就是为什么有时您会在 10-15 MB
上失败
因为,你不需要知道这里的impl,你只需要调用socket.setReceiveBufferSize(11728640);
,它就会解决你的问题。 impl 是 LocalSocketImpl
class (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) 设置时,内核将这个值加倍(以允许 space 用于簿记开销),并且这个加倍的值由 getsockopt( 2).参见 link:http://man7.org/linux/man-pages/man7/socket.7.html
现在,您的套接字有双倍大小的缓冲区 11728640 KB。您不应该遇到“内存不足”问题。
请注意 heap space 与 socket 无关。 Socket 与 Buffer 有关。
默认大小为 4K。您可以在此处找到此信息。 https://developer.android.com/reference/java/net/SocketOptions.html#SO_RCVBUF
SO_RCVBUF
常数是提示 OS 相应地改变 ReceiveBuffer 的大小。
我不断收到 "out of memory" 问题。我看到很多线程,我明白 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);
socket.setReceiveBufferSize(11728640);
//11.72864 MB -- 这就是为什么有时您会在 10-15 MB
因为,你不需要知道这里的impl,你只需要调用socket.setReceiveBufferSize(11728640);
,它就会解决你的问题。 impl 是 LocalSocketImpl
class (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) 设置时,内核将这个值加倍(以允许 space 用于簿记开销),并且这个加倍的值由 getsockopt( 2).参见 link:http://man7.org/linux/man-pages/man7/socket.7.html
现在,您的套接字有双倍大小的缓冲区 11728640 KB。您不应该遇到“内存不足”问题。
请注意 heap space 与 socket 无关。 Socket 与 Buffer 有关。
默认大小为 4K。您可以在此处找到此信息。 https://developer.android.com/reference/java/net/SocketOptions.html#SO_RCVBUF
SO_RCVBUF
常数是提示 OS 相应地改变 ReceiveBuffer 的大小。