Java 什么';DataOutputStream和ObjectOutputStream之间的区别是什么?
我正在学习Java中的套接字编程。我见过一些客户机/服务器应用程序示例,其中一些使用Java 什么';DataOutputStream和ObjectOutputStream之间的区别是什么?,java,android,sockets,Java,Android,Sockets,我正在学习Java中的套接字编程。我见过一些客户机/服务器应用程序示例,其中一些使用DataOutputStream,另一些使用ObjectOutputStream 这两者有什么区别 有性能差异吗?DataInput/OutputStream通常性能更好,因为它更简单。它只能读/写基本类型和字符串 ObjectInput/OutputStream可以读取/写入任何对象类型以及原语。如果要发送复杂的数据,它的效率较低,但使用起来容易得多 我认为Object*流是最好的选择,直到您知道它的性能是一个
DataOutputStream
,另一些使用ObjectOutputStream
这两者有什么区别
有性能差异吗?DataInput/OutputStream通常性能更好,因为它更简单。它只能读/写基本类型和字符串 ObjectInput/OutputStream可以读取/写入任何对象类型以及原语。如果要发送复杂的数据,它的效率较低,但使用起来容易得多
我认为Object*流是最好的选择,直到您知道它的性能是一个问题。
DataOutputStream
和ObjectOutputStream
:在处理基本类型时,除了ObjectOutputStream
创建的头之外没有任何区别
使用ObjectOutputStream
类,可以将实现Serializable
的类的实例写入输出流,并可以使用ObjectInputStream
读回
DataOutputStream
只能处理基本类型 只有实现java.io.Serializable
接口的对象才能使用ObjectOutputStream
写入流。原始数据类型也可以使用DataOutput中的适当方法写入流。也可以使用writeUTF方法写入字符串。但另一方面,DataInputStream
允许应用程序以可移植的方式将基本Java数据类型写入输出流
这可能对几年后仍在寻找答案的人有用。。。根据我在最近的一个JVM(1.851)上的测试,
ObjectOutput/InputStream
读/写一个庞大的double数组的速度几乎是DataOutput/InputStream
的2倍
下面是编写1000万项数组的结果(对于100万项,结果基本相同)。为了完整起见,我还包括了文本格式(BufferedWriter/Reader):
TestObjectStream written 10000000 items, took: 409ms, or 24449.8778 items/ms, filesize 80390629b
TestDataStream written 10000000 items, took: 727ms, or 13755.1582 items/ms, filesize 80000000b
TestBufferedWriter written 10000000 items, took: 13700ms, or 729.9270 items/ms, filesize 224486395b
阅读:
TestObjectStream read 10000000 items, took: 250ms, or 40000.0000 items/ms, filesize 80390629b
TestDataStream read 10000000 items, took: 424ms, or 23584.9057 items/ms, filesize 80000000b
TestBufferedWriter read 10000000 items, took: 6298ms, or 1587.8057 items/ms, filesize 224486395b
我相信Oracle已经对JVM进行了大量优化,以便在上一个Java版本中使用ObjectStream
s,因为这是写入/读取数据(包括序列化)的最常见方式,因此位于Java性能关键路径上
看来今天再也没有什么理由使用DataStream
s了。“不要试图智胜JVM”,只需使用最简单的方法,即ObjectStream
s:)
以下是测试代码:
class Generator {
private int seed = 1235436537;
double generate(int i) {
seed = (seed + 1235436537) % 936855463;
return seed / (i + 1.) / 524323.;
}
}
class Data {
public final double[] array;
public Data(final double[] array) {
this.array = array;
}
}
class TestObjectStream {
public void write(File dest, Data data) {
try (ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(dest)))) {
for (int i = 0; i < data.array.length; i++) {
out.writeDouble(data.array[i]);
}
} catch (IOException e) {
throw new RuntimeIoException(e);
}
}
public void read(File dest, Data data) {
try (ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(new FileInputStream(dest)))) {
for (int i = 0; i < data.array.length; i++) {
data.array[i] = in.readDouble();
}
} catch (IOException e) {
throw new RuntimeIoException(e);
}
}
}
class TestDataStream {
public void write(File dest, Data data) {
try (DataOutputStream out = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(dest)))) {
for (int i = 0; i < data.array.length; i++) {
out.writeDouble(data.array[i]);
}
} catch (IOException e) {
throw new RuntimeIoException(e);
}
}
public void read(File dest, Data data) {
try (DataInputStream in = new DataInputStream(new BufferedInputStream(new FileInputStream(dest)))) {
for (int i = 0; i < data.array.length; i++) {
data.array[i] = in.readDouble();
}
} catch (IOException e) {
throw new RuntimeIoException(e);
}
}
}
class TestBufferedWriter {
public void write(File dest, Data data) {
try (BufferedWriter out = new BufferedWriter(new FileWriter(dest))) {
for (int i = 0; i < data.array.length; i++) {
out.write(Double.toString(data.array[i]));
out.newLine();
}
} catch (IOException e) {
throw new RuntimeIoException(e);
}
}
public void read(File dest, Data data) {
try (BufferedReader in = new BufferedReader(new FileReader(dest))) {
String line = in.readLine();
int i = 0;
while (line != null) {
if(!line.isEmpty()) {
data.array[i++] = Double.parseDouble(line);
}
line = in.readLine();
}
} catch (IOException e) {
throw new RuntimeIoException(e);
}
}
}
@Test
public void testWrite() throws Exception {
int N = 10000000;
double[] array = new double[N];
Generator gen = new Generator();
for (int i = 0; i < array.length; i++) {
array[i] = gen.generate(i);
}
Data data = new Data(array);
Map<Class, BiConsumer<File, Data>> subjects = new LinkedHashMap<>();
subjects.put(TestDataStream.class, new TestDataStream()::write);
subjects.put(TestObjectStream.class, new TestObjectStream()::write);
subjects.put(TestBufferedWriter.class, new TestBufferedWriter()::write);
subjects.forEach((aClass, fileDataBiConsumer) -> {
File f = new File("test." + aClass.getName());
long start = System.nanoTime();
fileDataBiConsumer.accept(f, data);
long took = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - start);
System.out.println(aClass.getSimpleName() + " written " + N + " items, took: " + took + "ms, or " + String.format("%.4f", (N / (double)took)) + " items/ms, filesize " + f.length() + "b");
});
}
@Test
public void testRead() throws Exception {
int N = 10000000;
double[] array = new double[N];
Data data = new Data(array);
Map<Class, BiConsumer<File, Data>> subjects = new LinkedHashMap<>();
subjects.put(TestDataStream.class, new TestDataStream()::read);
subjects.put(TestObjectStream.class, new TestObjectStream()::read);
subjects.put(TestBufferedWriter.class, new TestBufferedWriter()::read);
subjects.forEach((aClass, fileDataBiConsumer) -> {
File f = new File("test." + aClass.getName());
long start = System.nanoTime();
fileDataBiConsumer.accept(f, data);
long took = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - start);
System.out.println(aClass.getSimpleName() + " read " + N + " items, took: " + took + "ms, or " + String.format("%.4f", (N / (double)took)) + " items/ms, filesize " + f.length() + "b");
});
}
类生成器{
私有整数种子=1235436537;
双生成(int i){
种子=(种子+1235436537)%936855463;
返回种子/(i+1.)/524323。;
}
}
类数据{
公共最终双[]数组;
公共数据(最终双[]数组){
this.array=数组;
}
}
类TestObjectStream{
公共无效写入(文件目的地、数据){
try(ObjectOutputStream out=newobjectoutputstream(new BufferedOutputStream(new FileOutputStream(dest))){
for(int i=0;i