#java #base64 #apache-commons #bufferedinputstream
Вопрос:
Я новичок в вводе-выводе Java, поэтому, пожалуйста, помогите.
Я пытаюсь обработать большой файл(например, файл pdf размером 50 МБ) с помощью библиотеки apache commons. Сначала я пытаюсь:
byte[] bytes = FileUtils.readFileToByteArray(file);
String encodeBase64String = Base64.encodeBase64String(bytes);
byte[] decoded = Base64.decodeBase64(encodeBase64String);
Но зная, что
FileUtils.readFileToByteArray в org.apache.commons.io
загрузит весь файл в память, я пытаюсь использовать BufferedInputStream
его для чтения файла по частям:
BufferedInputStream bis = new BufferedInputStream(inputStream);
StringBuilder pdfStringBuilder = new StringBuilder();
int byteArraySize = 10;
byte[] tempByteArray = new byte[byteArraySize];
while (bis.available() > 0) {
if (bis.available() < byteArraySize) { // reaching the end of file
tempByteArray = new byte[bis.available()];
}
int len = Math.min(bis.available(), byteArraySize);
read = bis.read(tempByteArray, 0, len);
if (read != -1) {
pdfStringBuilder.append(Base64.encodeBase64String(tempByteArray));
} else {
System.err.println("End of file reached.");
}
}
byte[] bytes = Base64.decodeBase64(pdfStringBuilder.toString());
Однако массив из 2 декодированных байтов выглядит не совсем так… … На самом деле, только 10 байт, что соответствует размеру моего временного массива… …
Кто-нибудь может, пожалуйста, помочь:
- что я делаю неправильно, читая файл по частям?
- почему декодированный массив байтов возвращает только 10 байтов во 2-м решении?
Заранее спасибо:)
Комментарии:
1. Честно говоря, я бы посоветовал вам попытаться закодировать весь файл сразу: 50 МБ на самом деле не так уж велики; максимальная длина строки Java составляет 2 ГБ.
2. @paulsm4 Спасибо за ваше предложение:)
3. Никогда не правильно использовать InputStream.available() для проверки конца потока. Вместо этого проверьте
read
, вернул ли метод отрицательное значение. Подробные сведения см. в документации .4. @VGR: Спасибо за ваш совет:) В качестве дополнительного вопроса, есть ли какие-либо предложения о том, как удалить/обрезать нули в конце последнего байтового массива?
5. Безусловно, существуют способы обработки только части массива байтов, но я бы сначала спросил, почему вы кодируете данные в base64, а затем сразу же декодируете эти же данные в bse64. Вы правы, что загрузка всего файла в память в память-плохая идея, но в конечном счете вы все равно делаете это (дважды!), так как вы все еще используете
bytes
переменную. Какую обработку файла вы на самом деле хотите выполнить?
Ответ №1:
После некоторого копания выясняется, что размер массива байтов должен быть кратен 3, чтобы избежать заполнения. После использования временного массива размером, кратным 3, программа может пройти.
Я просто меняюсь
int byteArraySize = 10;
быть
int byteArraySize = 1024 * 3;