使用Bytebuffer写出的返回与简单的写出不同

Abo*_*ank 4 java bytebuffer randomaccessfile

我正在尝试将字节数据写入文件并进行优化,我希望减少写入文件的次数.

目前,我正在使用:

try (RandomAccessFile out = new RandomAccessFile(file, "rw")) {

    for(int i = 0; i < totalPkts; i++) {
        out.writeInt(data.get(i));
    }
}
Run Code Online (Sandbox Code Playgroud)

这样可以正常工作,但由于有很多out.write调用,所以速度很慢.

所以相反,我试图用a ByteBuffer来代替:

try (RandomAccessFile out = new RandomAccessFile(file, "rw")) {
    ByteBuffer buffer = ByteBuffer.allocate(totalPkts*4); // prevent BufferOverflow

    for(int i = 0; i < totalPkts; i++) {
        buffer.putInt(data.get(i));
    }
    out.write(buffer.array());
}
Run Code Online (Sandbox Code Playgroud)

这两种方法生成的文件大小不同.该ByteBuffer文件几乎比普通输出文件大整整mb.这可以解释为什么差异会说他们不一样.

我尝试使用DataOutputStream,结果是一样的.使用的文件ByteBuffer仍然比不使用的文件大约1mb ByteBuffer.

Mar*_*ius 7

使用ByteBuffer编写文件时更大的原因是您初始化ByteBuffer的原因.当您只是使用时writeInt(int),您只编写需要编写的数据.但是,当你创建ByteBuffer时,你创建它比它需要的大,以防止我理解的溢出.但是,这也意味着从该array()方法返回的基础数组也比它需要的大.由于数组不理解位置和限制,因此在编写数组时,所有数据和之后的空白空间都会被写入,从而导致文件较大.你需要做的是将所有数据放入缓冲区后,需要翻转缓冲区,然后创建一个长度与数据库相同的新数组.limit()缓冲区(一旦翻转),然后get(byte[])缓冲区中的所有数据.拥有数组后,您需要编写它.

这就是我所说的:

try (RandomAccessFile out = new RandomAccessFile(file, "rw")) {
    ByteBuffer buffer = ByteBuffer.allocate(totalPkts*4);

    for(int i = 0; i < totalPkts; i++) {
        buffer.putInt(data.get(i));
    }

    buffer.flip();
    byte[] data = new byte[buffer.limit()];
    buffer.get(data);
    out.write(data);
}
Run Code Online (Sandbox Code Playgroud)