我想知道我是否可以获得解决问题的指导......
你看我正试图接受Socket编程;我设法创建了一个客户端和服务器;服务器写入客户端没问题; 我甚至设法使用
发送文件byte [] mybytearray = new byte [(int)myFile.length()];
FileInputStream fis = new FileInputStream(myFile);
在服务器端。 在客户端
byte [] mybytearray = new byte [filesize];
InputStream is = sock.getInputStream();
FileOutputStream fileos = new FileOutputStream("Filename.dat");
BufferedOutputStream bufferos = new BufferedOutputStream(fileos);
bytesRead = is.read(mybytearray,0,mybytearray.length);
current = bytesRead;
do {
bytesRead =
is.read(mybytearray, current, (mybytearray.length-current));
if(bytesRead >= 0) current += bytesRead;
} while(bytesRead > -1);
bufferos.write(mybytearray, 0 , current);
bufferos.flush();
long end = System.currentTimeMillis();
System.out.println(end-start);
bufferos.close();
我的问题是我无法发送大文件;我继续得到 “线程中的异常”主“java.lang.OutOfMemoryError:Java堆空间”
如何管理从服务器向客户端发送大文件的任何想法或指示?我的意思是大小说600 MB左右...... 任何想法? 非常感谢...谢谢
答案 0 :(得分:5)
好吧,您的堆当前不得不尝试保存'mybytearray',这是您尝试接收的文件的大小(大概)。您需要将bos.write()操作移动到循环内,并使'mybytearray'成为固定大小。以下是将一个流复制到另一个流的示例,该流并不真正关心流式传输数据的大小:
public static void stream(InputStream in, OutputStream out)
throws IOException {
byte[] buf = new byte[1024];
int bytesRead = 0;
try {
while (-1 != (bytesRead = in.read(buf, 0, buf.length))) {
out.write(buf, 0, bytesRead);
}
} catch (IOException e) {
log.error("Error with streaming op: " + e.getMessage());
throw (e);
} finally {
try{
in.close();
out.flush();
out.close();
} catch (Exception e){}//Ignore
}
}
答案 1 :(得分:4)
由于您要将mybytearray
分配为filesize
,因此内存不足。一种可能的解决方案是使用更大的堆调用JVM;例如-Xmx1G
。
然而,另一点是你是否需要将整个文件读入内存 - 在服务器端,这绝对不是的情况:你可以简单地将文件读成一个固定大小的数组,然后将这些块写入输出流。这样,当服务器尝试将大文件发送回客户端时,服务器的内存占用量不会增加。
答案 2 :(得分:3)
不要将完整的文件读入RAM以便发送,而是以chunkwise方式发送文件。
byte [] mybytearray = new byte [(int)myFile.length()];
如果(int)myFile.length()
超过内存,就不好了。
相反,请使用
byte [] buffer= new byte[4096];
左右并制作一个循环,从文件中读取并发送到套接字。
答案 3 :(得分:-2)
这意味着JVM内存不足..所以你应该基本上增加JVM堆空间..所以我认为问题不在于发送大文件..