Как я усекаю целое число Java, чтобы соответствовать / расширить к данному количеству байтов? - PullRequest
1 голос
/ 04 мая 2011

Я проектирую формат архива (просто для удовольствия) на Java, используя этот шаблон -

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

из PHP Безопасный способ загрузки файлов с множеством элементов и их сохранения .

У меня проблемы с поиском значений количества файлов и т. Д., Но я не знаю, как расширить целое число до 4 байтов.

Это похоже на это - Какобрезать строку Java, чтобы она соответствовала заданному количеству байтов после кодирования UTF-8?

Ответы [ 2 ]

5 голосов
/ 04 мая 2011

Используйте реализацию DataOutput / DataInput для записи / чтения этого формата, он сделает большую часть работы за вас. Классические реализации: DataOutputStream и 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);
// ...

Чтение работает почти так же.

Обратите внимание, что они используют big endian . Вам нужно будет проверить (или указать), использует ли ваш формат переменные с прямым или младшим порядковым номером.

3 голосов
/ 04 мая 2011

Вы можете преобразовать int в 4 байта следующим образом:

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;
}

Это поместит их в порядок с прямым порядком байтов, который часто используется для транспорта (см. Порядковый номер ).В качестве альтернативы, если вы уже имеете дело с OutputStream, вы можете заключить его в DataOutputStream и просто использовать writeInt().Например, согласно вашему шаблону:

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

Обратите внимание, что writeLong() на самом деле составляет 8 байтов.Я не уверен, почему вы хотите использовать 10, и я думаю, что 8 из long - это достаточно.

...