2013-02-26 4 views
1

Я пытаюсь загрузить файл на сервер (127.0.0.1) из blobstore с помощью GAE, но принимающий сервер даст мне ошибку «The загруженный файл был загружен только частично ». Я также отправляю один параметр в запросе, и он правильно получен сервером.GAE Загрузить файл POST-запрос (URLConnection) - ошибка: загруженный файл был только частично загружен

String url = "http://127.0.0.1/"; 
String charset = "UTF-8"; 

FileService fileService = FileServiceFactory.getFileService(); 
AppEngineFile appEngineFile = fileService.getBlobFile(new BlobKey("blob key")); 

String param = "my param"; 
File binaryFile = new File(appEngineFile.getFullPath()); 
String boundary = Long.toHexString(System.currentTimeMillis()); // Just generate some unique random value. 
String CRLF = "\r\n"; // Line separator required by multipart/form-data. 

URLConnection connection = new URL(url).openConnection(); 
connection.setDoOutput(true); 
connection.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary); 
PrintWriter writer = null; 
try { 
    OutputStream output = connection.getOutputStream(); 
    writer = new PrintWriter(new OutputStreamWriter(output, charset), true); // true = autoFlush, important! 

    // Send normal param. 
    writer.append("--" + boundary).append(CRLF); 
    writer.append("Content-Disposition: form-data; name=\"api_password\"").append(CRLF); 
    writer.append("Content-Type: text/plain; charset=" + charset).append(CRLF); 
    writer.append(CRLF); 
    writer.append(param).append(CRLF).flush(); 

    // Send binary file. 
    writer.append("--" + boundary).append(CRLF); 
    writer.append("Content-Disposition: form-data; name=\"file\"; filename=\"" + binaryFile.getName() + "\"").append(CRLF); 
    writer.append("Content-Type: application/octet-stream").append(CRLF); 
    writer.append("Content-Transfer-Encoding: binary").append(CRLF); 
    writer.append(CRLF).flush(); 
    InputStream input = null; 
    try { 

    BlobInfoFactory blobInfoFactory = new BlobInfoFactory(); 
    BlobInfo blobInfo = blobInfoFactory.loadBlobInfo(new BlobKey("blob key")); 
    Long blobSize = blobInfo.getSize(); 
    ByteArrayOutputStream buffer = new ByteArrayOutputStream(); 

    //max read on fetch 
    long maxReadFetch = 1015807; 

    //read the file in one time temporary 
    long i = 0; 
    long start = 0; 
    long end = 0; 
    while(i < blobSize) { 

    start = i; 
    end = i + maxReadFetch; 
    //determine end 
    if(end > blobSize) { 
    end = blobSize; 
    } 
    buffer.write(blobstoreService.fetchData(new BlobKey("blob key"), start, end)); 
    i += maxReadFetch; 

    } 

    output.write(buffer.toByteArray()); 

     output.flush(); // Important! Output cannot be closed. Close of writer will close output as well. 

    } finally { 
     if (input != null) try { input.close(); } catch (IOException logOrIgnore) {} 
    } 
    writer.append(CRLF).flush(); // CRLF is important! It indicates end of binary boundary. 

    // End of multipart/form-data. 
    writer.append("--" + boundary + "--").append(CRLF); 


    //resp part 
InputStream responseStream = new BufferedInputStream(connection.getInputStream()); 

BufferedReader responseStreamReader = new BufferedReader(new InputStreamReader(responseStream)); 

StringBuilder stringBuilder = new StringBuilder(); 
String line2; 
while ((line2 = responseStreamReader.readLine()) != null) 
{ 
    stringBuilder.append(line2).append("\n"); 
} 
responseStreamReader.close(); 

String response = stringBuilder.toString(); 
resp.getWriter().write(response); 
} finally { 
    if (writer != null) writer.close(); 
} 
+0

почему вы пишете каплю к ByteArrayOutputStream вместо conneciton OutputStream? вы любите использовать всю свою память? – jtahlborn

+0

euh no;) как я должен отправить его в цикле? –

+1

изменить 'buffer.write (' to 'output.write (' ... – jtahlborn

ответ

0

Так я это исправить здесь мое решение

FileService fileService = FileServiceFactory.getFileService(); 
AppEngineFile appEngineFile = fileService.getBlobFile(new BlobKey(video.getBlobkey())); 

String param = "4166764c675120921f348e64ca10148e8ff6d5df"; 
File binaryFile = new File(appEngineFile.getFullPath()); 
String boundary = Long.toHexString(System.currentTimeMillis()); // Just generate some unique random value. 
String CRLF = "\r\n"; // Line separator required by multipart/form-data. 

URLConnection connection = new URL(url).openConnection(); 
connection.setDoOutput(true); 
connection.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary); 
BufferedOutputStream writer = null; 

OutputStream output = connection.getOutputStream(); 
writer = new BufferedOutputStream(output); // true = autoFlush, important! 

// Send normal param. 
writer.write(("--" + boundary + CRLF).getBytes()); 
writer.write(("Content-Disposition: form-data; name=\"api_password\"" + CRLF).getBytes()); 
writer.write(("Content-Type: text/plain; charset=" + charset + CRLF).getBytes()); 
writer.write((CRLF).getBytes()); 
writer.write((param + CRLF).getBytes()); 
writer.flush(); 

// Send binary file. 
writer.write(("--" + boundary + CRLF).getBytes()); 
writer.write(("Content-Disposition: form-data; name=\"file\"; filename=\"" + binaryFile.getName() + "\"" + CRLF).getBytes()); 
writer.write(("Content-Type: application/octet-stream" + CRLF).getBytes()); 
writer.write(("Content-Transfer-Encoding: binary" + CRLF).getBytes()); 
writer.write((CRLF).getBytes()); 
writer.flush(); 
InputStream input = null; 
try { 

    BlobInfoFactory blobInfoFactory = new BlobInfoFactory(); 
    BlobInfo blobInfo = blobInfoFactory.loadBlobInfo(new BlobKey(video.getBlobkey())); 
    Long blobSize = blobInfo.getSize(); 

    //max read on fetch 
    long maxReadFetch = 1015807; 

    //read the file in one time temporary 
    long i = 0; 
    long start = 0; 
    long end = 0; 
    while(i < blobSize) { 

     start = i; 
     end = i + maxReadFetch; 
     //determine end 
     if(end > blobSize) { 
      end = blobSize; 
     } else { 
      end--; 
     } 
     writer.write(blobstoreService.fetchData(new BlobKey(video.getBlobkey()), start, end)); 
     i += maxReadFetch; 

    } 

    writer.flush(); // Important! Output cannot be closed. Close of writer will close output as well. 

} finally { 
    if (input != null) try { input.close(); } catch (IOException logOrIgnore) {} 
} 
writer.write((CRLF).getBytes()); 
writer.flush(); // CRLF is important! It indicates end of binary boundary. 

// End of multipart/form-data. 
writer.write(("--" + boundary + "--" + CRLF).getBytes()); 
writer.flush(); 

//response part 
InputStream responseStream = new BufferedInputStream(connection.getInputStream()); 

BufferedReader responseStreamReader = new BufferedReader(new InputStreamReader(responseStream)); 

StringBuilder stringBuilder = new StringBuilder(); 
String line2; 
while ((line2 = responseStreamReader.readLine()) != null) 
{ 
    stringBuilder.append(line2).append("\n"); 
} 
responseStreamReader.close(); 

String response = stringBuilder.toString(); //JSON data 
return response; 
0

Поскольку ошибка «Загруженный файл был загружен только частично» является результатом отмены загрузки, я думаю, что ваш запрос GAE прерывается из, может быть 30s предела исполнения или исключения до writer.append("--" + boundary + "--").append(CRLF); происходит. Может быть, выводить логические операторы, чтобы увидеть, где код останавливается.

 Смежные вопросы

  • Нет связанных вопросов^_^