使用套接字编程发送文件(大)

时间:2011-11-02 14:01:09

标签: java sockets

我想知道我是否可以获得解决问题的指导......

你看我正试图接受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左右...... 任何想法? 非常感谢...谢谢

4 个答案:

答案 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堆空间..所以我认为问题不在于发送大文件..