我想将仅对象的数据成员的值写入文件,所以在这里我不能使用序列化,因为它写了很多其他我不需要的信息。这是我用两种方式实现的。一个使用字节缓冲区而另一个不使用它。
不使用ByteBuffer: 第一种方法
public class DemoSecond {
byte characterData;
byte shortData;
byte[] integerData;
byte[] stringData;
public DemoSecond(byte characterData, byte shortData, byte[] integerData,
byte[] stringData) {
super();
this.characterData = characterData;
this.shortData = shortData;
this.integerData = integerData;
this.stringData = stringData;
}
public static void main(String[] args) {
DemoSecond dClass= new DemoSecond((byte)'c', (byte)0x7, new byte[]{3,4},
new byte[]{(byte)'p',(byte)'e',(byte)'n'});
File checking= new File("c:/objectByteArray.dat");
try {
if (!checking.exists()) {
checking.createNewFile();
}
// POINT A
FileOutputStream bo = new FileOutputStream(checking);
bo.write(dClass.characterData);
bo.write(dClass.shortData);
bo.write(dClass.integerData);
bo.write(dClass.stringData);
// POINT B
bo.close();
} catch (FileNotFoundException e) {
System.out.println("FNF");
e.printStackTrace();
} catch (IOException e) {
System.out.println("IOE");
e.printStackTrace();
}
}
}
使用字节缓冲区:还有一件事是数据成员的大小将始终保持固定,即characterData = 1byte,shortData = 1byte,integerData = 2byte和stringData = 3byte。所以这个类的总大小是7byte 总是
第二种方法
// POINT A
FileOutputStream bo = new FileOutputStream(checking);
ByteBuffer buff= ByteBuffer.allocate(7);
buff.put(dClass.characterData);
buff.put(dClass.shortData);
buff.put(dClass.integerData);
buff.put(dClass.stringData);
bo.write(buff.array());
// POINT B
我想知道两种方法中的哪一种更优化?并且也请理由。
上面的类 DemoSecond 只是一个示例类。
我的原始类将是大小为5到50个字节。我不认为这里的大小可能是问题。 但我的每个类都是固定大小的,如 DemoSecond
还有这么多类型的文件,我将在二进制文件中写入。
PS
如果我使用序列化,它还会写出“characterData”,“shortData”,“integerData”,“stringData”这个词,以及其他我不想在文件中写入的信息。我在这里看到的只是他们的价值观。在这个例子中,它是:'c',7,3,4'p','e','n'。我想只将这个7字节写入文件,而不是其他对我有用的信息。
答案 0 :(得分:2)
在进行文件I / O时,您应该记住,I / O操作可能比输出代码中CPU完成的任何工作要慢得多。首先,I / O的成本是与您正在写入的数据量成比例的量,加上每次执行I / O操作系统调用的固定成本。
因此,在您的情况下,您希望最大限度地减少执行写入操作系统调用的次数。这是通过缓冲应用程序中的数据来完成的,因此应用程序执行的操作系统调用很少。
正如您所做的那样,使用字节缓冲区是实现此目的的一种方法,因此您的ByteBuffer
代码将比FileOutputStream
代码更有效。
但还有其他一些考虑因素。您的示例没有执行很多写操作。所以无论如何它可能会非常快。任何优化都可能是不成熟的优化。优化往往会使代码更复杂,更难理解。要了解您的ByteBuffer
代码,读者需要了解ByteBuffer
如何 如果您更改了文件格式,则更有可能引入FileOutputStream
代码的错误(例如,缓冲区太小)。
通常会完成输出缓冲。因此,Java已经提供了帮助您的代码,这一点不应该让您感到惊讶。该代码将由专家编写,经过测试和调试。除非您有特殊要求,否则应始终使用此类代码而不是自己编写代码。我所指的代码是ByteBuffer
类。
要使用它,只需调整不使用BufferedOutputStream
的代码,方法是将打开文件的代码行更改为
ByteBuffer
答案 1 :(得分:0)
这两种方法的区别仅在于分配的字节缓冲区。
如果您对文件的不必要的写操作感到担忧,那么您已经可以使用BufferedOutputStream
,内部分配缓冲区,如果您多次写入相同的输出流,则效率肯定更高而不是每次手动分配缓冲区。
答案 2 :(得分:0)
在FileOutputStream周围的BufferedOutputStream周围使用DataOutputStream是最简单的。
注意:您无法挤压" shortData'变成一个字节。使用DataOutputStream的各种原语,并在读取它们时使用相应的DataInputStream。