使用ObjectOutputStream时估计磁盘上文件的大小

时间:2012-06-26 02:46:41

标签: java size fileoutputstream objectoutputstream

我正在尝试将表空间数据从表格写入文件。但是在写入磁盘之前,我需要知道磁盘上数据的确切大小。举个例子,假设我使用以下代码写入磁盘:

    FileOutputStream fos = new FileOutputStream("t.tmp",false);
    ObjectOutputStream oos = new ObjectOutputStream(fos);
    oos.writeInt(gid);
    oos.writeUTF(fullname);
    oos.writeInt(d.shape.length);
    oos.write(d.shape);

    oos.close();
    fos.close();

我原以为磁盘上的文件大小等于:

size= 4B {for gid, int} + fullname.getBytes.length() {string} + 4B {d.shape.length, int} + d.shape.length

但实际上,这与磁盘上的实际文件大小非常不同。

我还注意到即使使用ObjectOutputstream创建一个空文件也会导致磁盘上的4B空间。

有关如何计算磁盘上文件大小的任何帮助吗?

(我无法将数据写入磁盘,然后读取实际大小。这会降低性能。相反,我需要根据存储在内存中的数据值计算磁盘上的数据大小。)

2 个答案:

答案 0 :(得分:2)

  

我正在尝试将表空间数据从表格写入文件。但在写入磁盘之前,我需要知道磁盘上数据的确切大小。

您不应该使用ObjectOutputStreamObjectOutputStream可以自动为您复杂的对象图表序列化 - 但这似乎不是您的要求之一。作为此序列化的一部分,ObjectOutputStream会写入一些流标头信息(这是您在开始时发现的4个字节),并且还会跟踪先前写入的对象,以便它可以写入特殊标记值而不是写出来整个对象。

相反,只需使用DataOutputStream即可。它提供了您想要的相同功能:

  

数据输出流允许应用程序以可移植的方式将原始Java数据类型写入输出流。然后,应用程序可以使用数据输入流来重新读取数据。

FileOutputStream fos = new FileOutputStream("t.tmp",false);
DataOutputStream dos = new DataOutputStream(fos);
dos.writeInt(gid);                 // write 4 bytes
dos.writeUTF(fullname);            // write 2 bytes of length, then variable length string (UTF encoded)
dos.writeInt(d.shape.length);      // write 4 bytes
dos.write(d.shape);                // write a variable length byte array

dos.close();
fos.close();

这里不会有任何意外(前提是您知道UTF编码的字符串将以多少字节结束),并且您可以通过算术来计算确切的文件大小。

(如果你处理的字符串不仅仅等同于一个字符的一个字节,你可以先使用字符集编码器将字符串渲染为一个字节数组。)

答案 1 :(得分:1)

假设你不介意浪费一些记忆,你可以先将它全部写到ByteArrayOutputStream,然后再大小。

ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(boas);
oos.writeInt(gid);
oos.writeUTF(fullname);
oos.writeInt(d.shape.length);
oos.write(d.shape);

oos.close();
boas.close();
int size = boas.size();