Таким образом, у меня есть некоторый код, который читает определенную сумму байтов из файла и возвращает получающийся массив байтов (это в основном используется для разделения на блоки файлов для отправки по сети как (в конечном счете) base64-закодированный текст ASCII).
Это хорошо работает, за исключением того, что, когда последний блок файла сгенерирован, это не полный блок. Поэтому получающийся массив байтов не полон. Однако это - постоянный размер, что означает, что файл повторно собран существует целый набор дополнительных данных (0, возможно) добавлен в конец.
Как я могу сделать его так, чтобы байт [] для последнего блока файла действительно только содержал данные, это должно? Код похож на это:
private byte[] readData(File f, int startByte, int chunkSize) throws Exception {
RandomAccessFile raf = new RandomAccessFile(f, "r");
raf.seek(startByte);
byte[] data = new byte[chunkSize];
raf.read(data);
raf.close();
return data;
}
Таким образом, если chunkSize больше, чем остающиеся байты в файле, байт в натуральную величину [] возвращается, но его единственное полунаполненное с данными.
Вам нужно будет проверить возвращаемое значение RandomAccessFile.read ()
, чтобы определить количество прочитанных байтов. Если он отличается от chunkSize, вам придется скопировать массив в меньший и вернуть его.
private byte[] readData(File f, int startByte, int chunkSize) throws Exception {
RandomAccessFile raf = new RandomAccessFile(f, "r");
raf.seek(startByte);
byte[] data = new byte[chunkSize];
int bytesRead = raf.read(data);
if (bytesRead != chunkSize) {
byte[] smallerData = new byte[bytesRead];
System.arraycopy(data, 0, smallerData, 0, bytesRead);
data = smallerData;
}
raf.close();
return data;
}
RandomAccessFile.read ()
возвращает количество прочитанных байтов, поэтому при необходимости вы можете скопировать массив:
private byte[] readData(File f, int startByte, int chunkSize) throws Exception {
RandomAccessFile raf = new RandomAccessFile(f, "r");
raf.seek(startByte);
byte[] data = new byte[chunkSize];
int read = raf.read(data);
raf.close();
if (read == data.length) return data;
else
return Arrays.copyOf(data, read);
}
Если вы используете Java pre-6, вам нужно реализовать Arrays.copyOf
самостоятельно:
byte[] r = new byte[read];
System.arraycopy(data, 0, r, 0, read);
return r;
Вы также можете использовать размер файла для вычисления оставшегося количества байтов.
private byte[] readData(File f, int startByte, int chunkSize) throws Exception {
RandomAccessFile raf = new RandomAccessFile(f, "r");
raf.seek(startByte);
int size = (int) Math.min(chunkSize, raf.length()-startByte);
byte[] data = new byte[size];
raf.read(data);
// TODO check the value returned by read (throw Exception or loop)
raf.close();
return data;
}
Таким образом, вы не создаете дополнительный массив и не нуждаетесь в копии. Наверное, не большое влияние.
Один важный момент IMO: проверьте значение, возвращаемое read
, я думаю, оно может быть меньше оставшихся байтов. В документации javadoc указано:
Число прочитанных байтов не более чем равно длине b