通过套接字在对象内发送文件字节

时间:2014-09-29 17:58:10

标签: java sockets tcp

我一直试图让这个工作几天,但我没有成功。

我想通过套接字客户端/服务器发送文件。唯一的区别是:我想发送一个包含文件字节的对象。

因此,客户端加载文件,读取 1024字节的块,将它们存储在对象中,然后将对象发送到服务器。由于文件可能大于1024字节,我想重复发送对象,但存储不同的字节(缓冲区读取它)。在服务器上,我想组成字节数组并将其保存为文件。

我使用1024的原因是因为我想避免任何类型的内存不足错误,如果文件是,请说4 GB。

我尝试在客户端上执行以下操作:

File file = new File("C:\\test\\test.txt");
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
byte[] bytes = new byte[1024];

FileTest ft = new FileTest();
ft.setName("Testing");
int counttest = 1;

while (bis.read(bytes) > 0) {
    ft.setCounttest(counttest);
    ft.setBytes(bytes);
    oos.writeObject(ft);
    counttest += 1;
}

在服务器上:

int bufferSize = socket.getReceiveBufferSize();
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("C:\\test\\test2.txt"));    
ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
byte[] bytes = new byte[bufferSize];

while (true) {
    FileTest ft = (FileTest) ois.readObject();
    if (ft != null) {
        System.out.println(ft.getName());
        bos.write(ft.getBytes());
    }
}

所以我测试了发送带有一系列数字的txt文件,并且服务器生成的test2.txt文件只出现了重复两次的前1024个字节块。此外,当在服务器中接收时,counttest整数永远不会增加。

知道怎么做到这一点吗?

提前致谢。

1 个答案:

答案 0 :(得分:1)

您正在遇到ObjectOutputStream尝试保留对象标识的效果。重复写入相同的对象实例将导致接收器端的相同的实例。这通常是一件好事,但如果您正在修改发送方端的对象并期望这些修改显示在接收方的末端,则会造成混淆。

因此,您有两个问题:

  1. 为了每次都发送数据,您需要每次都创建一个新的FileTest实例,或者使用writeUnshared()方法。
  2. 由于此身份保留行为,您需要定期reset() ObjectOutputStream,以便永远保留所有这些实例(并可能导致客户端或服务器上的OOME)。