开发者

How do I truncate a java integer to fit/exand to a given number of bytes?

开发者 https://www.devze.com 2023-03-02 22:28 出处:网络
I am designing an archive format(Just for fun) in Java using this template- First 4 bytes: Number of files in the archive

I am designing an archive format(Just for fun) in Java using this template-

First 4 bytes: Number of files in the archive
Next 4 bytes: Number of bytes in the filename
Next N bytes: Filename
Next 10 bytes: Number of bytes in the file
Next N bytes: File contents

from PHP Safe way to download mutliple files and save them.

I am having on trouble with finding the values of the number of files etc. but I don't know how to expand an integer into 4 bytes.

Is it similar to this- How do I truncate a java string to fit in a given number of bytes, o开发者_运维知识库nce UTF-8 encoded?


Use a DataOutput/DataInput implementation to write/read that format, it does most of the work for you. The classical implementations are DataOutputStream and DataInputStream:

DataOutputStream dos = new DataOutputStream(outputStream);
dos.writeInt(numFiles);
// for each file name
byte[] fn = fileName.getBytes("UTF-8"); // or whichever encoding you chose
dos.writeInt(fn.length);
dos.write(fn);
// ...

Reading works pretty much the same.

Note that these use big endian. You'll have to check (or specify) if your format uses big- or little-endian.


You can convert an int into 4 bytes like this:

public byte[] getBytesForInt(int value) {
    byte[] bytes = new byte[4];
    bytes[0] = (byte) ((value >> 24) & 0xFF);
    bytes[1] = (byte) ((value >> 16) & 0xFF);
    bytes[2] = (byte) ((value >> 8) & 0xFF);
    bytes[3] = (byte) (value & 0xFF);
    return bytes;
}

This would put them in big-endian order as often used for transport (see Endianness). Alternatively if you're already dealing with an OutputStream you could wrap it with a DataOutputStream and just use writeInt(). For example as per your template:

FileOutputStream fileOut = new FileOutputStream("foo.dat");
DataOutputStream dataOut = new DataOutputStream(fileOut);
dataOut.writeInt(numFiles);
dataOut.writeInt(numBytesInName);
dataOut.writeUTF(filename);
dataOut.writeLong(numBytesInFile);
dataOut.write(fileBytes);

Note that the writeLong() is actually 8 bytes. I'm not sure why you'd want to use 10 and I imagine 8 from a long is plenty.

0

精彩评论

暂无评论...
验证码 换一张
取 消