我想仅将对象的数据成员的值写入文件,因此这里我不能使用序列化,因为它会写入很多内容其他我不需要的信息。这是我通过两种方式实现的。一种使用字节缓冲区,另一种则不使用它。
不使用 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 ALWAYS
第二种方法
// 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”以及我不想写入文件的其他信息。我在这里关心的是仅他们的值(value)观。在此示例中,其为:'c', 7, 3,4'p','e','n'。我只想将这 7 个字节写入文件,而不是其他对我来说无用的信息。
最佳答案
当您进行文件 I/O 时,您应该记住,I/O 操作可能比 CPU 在输出代码中完成的任何工作慢得多。第一个近似值是,I/O 成本与您正在写入的数据量成正比,加上执行 I/O 的每个操作系统调用的固定成本。
因此,在您的情况下,您希望最大限度地减少进行写入操作的操作系统调用次数。这是通过在应用程序中缓冲数据来完成的,因此应用程序很少执行较大的操作系统调用。
正如您所做的那样,使用字节缓冲区是实现此目的的一种方法,因此您的 ByteBuffer
代码将比 FileOutputStream
代码更高效。
但还有其他考虑因素。您的示例没有执行很多写入操作。所以无论如何它可能会非常快。任何优化都可能是过早的优化。优化往往会使代码变得更加复杂且难以理解。要理解 ByteBuffer
代码,读者除了需要了解 FileOutputStream< 的所有内容之外,还需要了解
代码。如果您更改文件格式,则更有可能在 ByteBuffer
的工作原理/ByteBuffer
代码中引入错误(例如,缓冲区太小)。
通常会进行输出缓冲。因此,Java 已经提供了可以帮助您的代码,您应该不会感到惊讶。该代码将由专家编写、测试和调试。除非您有特殊要求,否则您应该始终使用此类代码而不是编写自己的代码。我指的代码是 BufferedOutputStream 类。
要使用它,只需调整不使用 ByteBuffer
的代码,方法是将打开文件的代码行更改为
OutputStream bo = new BufferedOutputStream(new FileOutputStream(checking));
关于java - 放入 ByteBuffer 然后将其写入文件比写入单个字段更有效,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24646231/