Как да качите двоичен файл с помощта на URLConnection

За да кача двоичен файл на URL, бях посъветван да използвам това ръководство. Файлът обаче не е в директория, а се съхранява в BLOB поле в MySql db. Полето 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 байта по-голям от размера, изведен от моя код.

Познанията ми за потоци, връзки и байт[] са твърде ограничени, за да разбера как да поправя това. Всички намеци се оценяват.


РЕДАКТИРАНЕ

Както беше предложено от коментатора, опитах също да напиша директно байта [], без да използвам 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