3

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

    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 空间。

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

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

4

2 回答 2

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 编码的 String 将结束多少字节),并且您可以通过算术计算出确切的文件大小。

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

于 2012-06-26T04:22:44.800 回答
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();
于 2012-06-26T02:53:59.817 回答