Java: Как “обрезать” массив байтов?

Таким образом, у меня есть некоторый код, который читает определенную сумму байтов из файла и возвращает получающийся массив байтов (это в основном используется для разделения на блоки файлов для отправки по сети как (в конечном счете) 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 больше, чем остающиеся байты в файле, байт в натуральную величину [] возвращается, но его единственное полунаполненное с данными.

7
задан Erin Drummond 17 December 2009 в 02:05
поделиться

3 ответа

Вам нужно будет проверить возвращаемое значение 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;
}
3
ответ дан 7 December 2019 в 12:21
поделиться

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;
2
ответ дан 7 December 2019 в 12:21
поделиться

Вы также можете использовать размер файла для вычисления оставшегося количества байтов.

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

0
ответ дан 7 December 2019 в 12:21
поделиться
Другие вопросы по тегам:

Похожие вопросы: