发送使用的FileInputStream / ObjectOutputStream的大文件(Send

2019-09-17 15:17发布

我需要我的家庭作业帮助,任何帮助将非常感激。 我可以给小文件没有问题。 但是,当我尝试发送比方说,一个1GB的文件字节数组发送的OutOfMemoryError,所以我需要一个更好的解决方案,从服务器发送文件到客户端。 我怎样才能提高此代码,发送大文件,请帮帮我。

服务器代码:

    FileInputStream fis = new FileInputStream(file);
    byte[] fileByte = new byte[fis.available()]; //This causes the problem.
    bytesRead = fis.read(fileByte);
    oos = new ObjectOutputStream(sock.getOutputStream());
    oos.writeObject(fileByte);

客户代码:

    ois = new ObjectInputStream(sock.getInputStream());
    byte[] file = (byte[]) ois.readObject();
    fos = new FileOutputStream(file);
    fos.write(file);

Answer 1:

刚刚拆分阵列较小的块,这样你就不需要分配任何大的阵列。

例如,你可以拆分成数组16Kb的块,如new byte[16384]并通过一个送他们一个。 在接收端,你将不得不等待,直到一个块可以完全读取,然后将它们存储的地方,并与下一个块开始。

但是,如果你不能够分配你需要在服务器端大小的整个阵列,您将无法存储所有,你会收到反正数据。

你也可以将其发送以节省带宽(与时间),来看看前压缩数据ZipOutputStreamZipInputStream



Answer 2:

不要读整个文件到内存中,使用一个小缓冲区,而你正在阅读的文件写道:

BufferedOutputStream bos = new BufferedOutputStream(sock.getOutputStream())

File file = new File("asd");
FileInputStream fis = new FileInputStream(file);
BufferedInputStream bis = new BufferedInputStream(fis);
byte[] buffer = new byte[1024*1024*10];
int n = -1;
while((n = bis.read(buffer))!=-1) {
  bos.write(buffer,0,n):
}

使用缓冲*优化写入和读取的流



Answer 3:

下面是我如何解决它:

客户代码:

 bis=new BufferedInputStream(sock.getInputStream());
 fos = new FileOutputStream(file);
 int n;
 byte[] buffer = new byte[8192];
 while ((n = bis.read(buffer)) > 0){
 fos.write(buffer, 0, n);}

服务器代码:

 bos= new BufferedOutputStream(sock.getOutputStream());
 FileInputStream fis = new FileInputStream(file);
 BufferedInputStream bis = new BufferedInputStream(fis);
 int n=-1;
 byte[] buffer = new byte[8192];
 while((n = bis.read(buffer))>-1) 
 bos.write(buffer,0,n);


Answer 4:

根据您是否拥有自己编写的代码中,有哪些解决这个问题,比如现有的库rmiio 。 如果你不使用RMI,只是普通的Java序列化,你可以使用DirectRemoteInputStream ,这是一种像一个序列化的InputStream。 (这个库也有类似的东西自动神奇地压缩数据的支持)。

其实,如果你发送文件数据,你会过得更好开沟对象流和使用的DataInput / DataOutput中流。 第一写的整数,指示文件的长度,则该字节直接复制到流中。 在接收侧,读取整数文件长度,然后读取正是许多字节。

当复制流之间的数据,使用一个小的,固定大小的字节[]移动输入和输出流之间的数据块在一个循环。 也有如何做到这一点正确可在网上(如@ ErikFWinter的答案)的例子不胜枚举。



文章来源: Sending big file using FileInputStream/ObjectOutputStream