reza
reza

Reputation: 1218

estimating size of file on disk when using ObjectOutputStream

I am trying to write my spatial data from a table to a file. But I need to know the exact size of the data on disk before writing to disk. As an example, let's say that I am writing to disk using the following code:

    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();

I was thinking that file size on disk is equal to:

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

but in fact, this is very different than the real file size on disk.

I also noticed that even creating an empty file using ObjectOutputstream leads to 4B space on disk.

Any help on how to calculate the file size on disk?

(I can't write the data to disk and then read the real size. This will lower the performance. Instead, I need to calculate the size of data on disk based on data values stored in memory.)

Upvotes: 3

Views: 2540

Answers (2)

Greg Kopff
Greg Kopff

Reputation: 16575

I am trying to write my spatial data from a table to a file. But I need to know the exact size of the data on disk before writing to disk.

You shouldn't use an ObjectOutputStream. An ObjectOutputStream can automatically serialise a complex graph of objects for you - but this doesn't appear to be one of your requirements. As part of this serialisation, the ObjectOutputStream writes some stream header information (this is the 4 bytes you discovered at the beginning), and also keeps track of objects written previously so that it can write special marker values rather than writing out the whole object again.

Instead, just use a DataOutputStream. It provides the same functionality you want:

A data output stream lets an application write primitive Java data types to an output stream in a portable way. An application can then use a data input stream to read the data back in.

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();

There won't be any surprises here (provided you know how many bytes your UTF encoded String will end up), and you can do the arithmetic to calculate what the exact file size will be.

(If you were dealing with strings that didn't just equate to one-character-one-byte, you could render the string to a byte array first using a charset encoder).

Upvotes: 2

wolfcastle
wolfcastle

Reputation: 5930

Assuming you don't mind wasting some memory, you can write it all out to a ByteArrayOutputStream first, then get the size.

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();

Upvotes: 1

Related Questions