我正在尝试将表空间数据从表格写入文件。但是在写入磁盘之前,我需要知道磁盘上数据的确切大小。举个例子,假设我使用以下代码写入磁盘:
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空间。
有关如何计算磁盘上文件大小的任何帮助吗?
(我无法将数据写入磁盘,然后读取实际大小。这会降低性能。相反,我需要根据存储在内存中的数据值计算磁盘上的数据大小。)
答案 0 :(得分:2)
我正在尝试将表空间数据从表格写入文件。但在写入磁盘之前,我需要知道磁盘上数据的确切大小。
您不应该使用ObjectOutputStream
。 ObjectOutputStream
可以自动为您复杂的对象图表序列化 - 但这似乎不是您的要求之一。作为此序列化的一部分,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();