Как загрузить бинарный файл с помощью URLConnection

Чтобы загрузить двоичный файл по URL-адресу, мне посоветовали использовать это руководство. Однако файл находится не в каталоге, а хранится в поле BLOB в базе данных MySql. Поле BLOB отображается как свойство byte[] в JPA:

byte[] binaryFile;

Я немного изменил код, взятый из руководства, таким образом:

HttpURLConnection connection = (HttpURLConnection ) new URL(url).openConnection();
// set some connection properties
OutputStream output = connection.getOutputStream();
PrintWriter writer = new PrintWriter(new OutputStreamWriter(output, CHARSET), true); 
// set some headers with writer
InputStream file = new ByteArrayInputStream(myEntity.getBinaryFile());
System.out.println("Size: " + file.available());
try {
    byte[] buffer = new byte[4096];
    int length;
    while ((length = file.read(buffer)) > 0) {
        output.write(buffer, 0, length);
    } 
    output.flush();
    writer.append(CRLF).flush();
    writer.append("--" + boundary + "--").append(CRLF).flush();
} 
// catch and close streams

Я не использую потоковую передачу по частям. Используемые заголовки:

username and password
Content-Disposition: form-data; name=\"file\"; filename=\"myFileName\"\r\nContent-Type: application/octet-stream"
Content-Transfer-Encoding: binary

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

Мои знания о потоках, соединениях и byte[] слишком ограничены, чтобы понять, как это исправить. Любые подсказки приветствуются.


РЕДАКТИРОВАТЬ

Как было предложено комментатором, я также попытался написать byte[] напрямую, без использования ByteArrayInputStream:

output.write(myEntity.getBinaryFile());

К сожалению, хост дает точно такой же ответ, как и в другую сторону.


person perissf    schedule 20.11.2012    source источник
comment
Почему вы передаете файл через BAIS? Почему бы просто не написать прямо из самого массива байтов?   -  person Jim Garrison    schedule 20.11.2012
comment
@JimGarrison Спасибо за подсказку, я обновил свой вопрос.   -  person perissf    schedule 20.11.2012
comment
Что произойдет, если вместо file.available() вы сделаете byte[] temp = myEntity.getBinaryFile(); и используете temp.length? Я подозреваю, что file.available() выключен.   -  person Jim Garrison    schedule 21.11.2012
comment
В этом случае file. available() был точным, давая точное количество байтов. Я только что решил проблему: используя подсказку, что в файле, полученном хостом, было слишком много байтов, я удалил заголовок Content-Transfer-Encoding и конечную строку, и теперь все в порядке. Все равно, спасибо за помощь!   -  person perissf    schedule 21.11.2012


Ответы (1)


Мой код был правильным.

Хост выдавал ошибку, потому что не ожидал заголовка Content-Transfer-Encoding. После его удаления все пошло нормально.

person perissf    schedule 20.11.2012