我的系统涉及通过TCP套接字发送大量数据和元数据。我发送一个包含各种元数据的对象,以及20个字节的数组。到目前为止,我一直在使用包含BufferedOutputStream的ObjectOutputStream来处理小例子(130kB数组)。我尝试达到67MB阵列的目标,但ObjectOutputStream无法处理那么多数据。我能够发送1MB数组,但writeObject()挂起2MB。
我听说DataOutputStream更快,但我宁愿不必将元数据编码为字节并在另一端解码。是否有一个很好的替代方案可以快速发送非常大的对象?
修改
我在每个write方法后都使用了reset()。我目前正在发送一个SignedObject,它包含我自己的Message对象,该对象包含20个数组以及许多元数据字段。我更喜欢把它全部打包,因为它非常方便,但我知道分离可能是唯一的方法。话虽这么说,我仍然需要确保所有传输都是安全的。
更新
所以我去吃午饭,回来了,并决定我试着弄清楚发送或接收端是否挂起了东西。然后它永远不会挂断。我可以继续成功发送最多4MB阵列,直到我用完堆(这是无关的,只是意味着我需要一台更好的计算机或更高效的处理)。所以我猜问题就消失了?并不意味着我不需要更好的传播方式,所以如果人们拥有它们,我会采取更多的想法。另外,我假设我一更新一次,就会再次停止工作......
答案 0 :(得分:1)
是否有一个很好的选择,能够快速发送非常大的物体?
在发送的对象之间使用ObjectOutputStream和reset()。除非你只有几MB的内存(其中你应该得到更多)你不会有问题。
与自己编码字节相比,ObjectOutputStream相当慢,但它可以很好地处理编码。网络上传速度更可能是您的限制因素。在这个例子中,它发送大约600 Mb / s,而大多数braodband连接大约500 kb / s(大约慢1000倍)
ServerSocket ss = new ServerSocket(0);
Socket s = new Socket("localhost", ss.getLocalPort());
final Socket s2 = ss.accept();
ss.close();
new Thread(new Runnable() {
@Override
public void run() {
int count = 0;
long start = System.nanoTime();
try {
ObjectInputStream in = new ObjectInputStream(
new InflaterInputStream(s2.getInputStream()));
while (in.readObject() != null) count++;
s2.close();
} catch (Exception e) {
e.printStackTrace();
}
long time = System.nanoTime() - start;
System.out.printf("Read %,d objects in %.3f seconds%n", count, time / 1e9);
}
}, "reader").start();
ObjectOutputStream oos = new ObjectOutputStream(
new DeflaterOutputStream(s.getOutputStream()));
for (int i = 0; i < 20; i++) {
byte[] bytes = new byte[67 * 1000 * 1000];
oos.writeObject(bytes);
oos.reset();
}
oos.writeObject(null); // poison pill
oos.close();
s.close();
打印
Read 20 objects in 21.644 seconds