我尝试使用GAE从blobstore上传文件到服务器(127.0.0.1),但接收服务器给我错误“上传的文件只是部分上传”。 我还在请求中发送了一个参数,服务器正确接收了该参数。
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 :(得分:0)
由于错误“上传的文件只是部分上传”是取消上传的结果,我认为您的GAE请求会在writer.append("--" + boundary + "--").append(CRLF);
发生之前从30秒的执行限制或异常中止。可能输出日志语句以查看代码停止的位置。
答案 1 :(得分: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;