我正在尝试使用apache commons httpclient 3.1将文件发送到IIS服务器,但是我的内存出错了。
InputStream is = FileService.getInputStream(fileName, FileService.HDD);
ByteArrayOutputStream fileToUpload = new ByteArrayOutputStream();
ByteArrayPartSource file = null;
try {
byte[] buffer = new byte[1024];
for (int len; (len = is.read(buffer)) != -1;)
fileToUpload.write(buffer, 0, len);
file = new ByteArrayPartSource(fileName, fileToUpload.toByteArray());
post.setContentChunked(false);
Part[] part = new Part[] { new FilePart(fileName, file)};
post.setRequestEntity(new MultipartRequestEntity(part, post.getParams()));
}
catch (OutOfMemoryError e) {
}
finally {
try {
if (is != null) is.close();
if (fileToUpload != null) fileToUpload.close();
} catch (IOException e) {
}
}
OutOfMemoryError发生在fileToUpload.toByteArray()。有没有办法以块的形式发送文件?我无法使用文件对象,因为我收到了权限错误。
我也尝试过不使用httpClient,但我仍然出现内存错误
InputStream fileToUpload = FileService.getInputStream(fileName, FileService.HDD);
OutputStream output = connection.getOutputStream();
PrintWriter writer = null;
try {
writer = new PrintWriter(new OutputStreamWriter(connection.getOutputStream(), "UTF-8"));
writer.println("--" + boundary);
writer.println("Content-Disposition: form-data; name=\"binaryFile\"; filename=\""+ fileName + "\"");
writer.println("Content-Type: application/octet-stream");
writer.println("Content-Transfer-Encoding: binary");
writer.println();
writer.flush();
LogService.info("FileSender#setFileToUpload() Before");
byte[] buffer = new byte[2048];
int bytesRead;
while ((bytesRead = fileToUpload.read(buffer)) != -1){
output.write(buffer, 0, bytesRead);
}
LogService.info("FileSender#setFileToUpload() After");
output.flush();
writer.println();
writer.flush();
writer.println("--" + boundary + "--");
} finally {
if (writer != null) writer.close();
if (output != null) output.close();
if (fileToUpload != null) fileToUpload.close();
}
答案 0 :(得分:0)
您需要对数据进行流式传输,因此它不会像以下内容一样存储在内存中:
InputStream is = FileService.getInputStream(fileName, FileService.HDD);
try {
InputStreamBody inputStreamBody = new InputStreamBody(is, fileName);
MultipartEntity entity = new MultipartEntity();
entity.addPart(fileName, inputStreamBody);
post.setEntity(entity);
httpClient.execute(post);
...
} finally {
is.close();
}
答案 1 :(得分:0)
在非httpclient版本中,尝试移动output.flush()
,以便在读取时通过网络发送您读取的块,而不是在刷新之前缓冲整个文件在内存中(您可能想要尝试其他块大小):
InputStream fileToUpload = FileService.getInputStream(fileName, FileService.HDD);
OutputStream output = connection.getOutputStream();
PrintWriter writer = null;
try {
writer = new PrintWriter(new OutputStreamWriter(connection.getOutputStream(), "UTF-8"));
writer.println("--" + boundary);
writer.println("Content-Disposition: form-data; name=\"binaryFile\"; filename=\""+ fileName + "\"");
writer.println("Content-Type: application/octet-stream");
writer.println("Content-Transfer-Encoding: binary");
writer.println();
writer.flush();
LogService.info("FileSender#setFileToUpload() Before");
byte[] buffer = new byte[2048];
int bytesRead;
while ((bytesRead = fileToUpload.read(buffer)) != -1){
output.write(buffer, 0, bytesRead);
output.flush();// <-----------------------------------
}// |
// |
LogService.info("FileSender#setFileToUpload() After");// |
// |
// -------------------------------------------------------
writer.println();
writer.flush();
writer.println("--" + boundary + "--");
} finally {
if (writer != null) writer.close();
if (output != null) output.close();
if (fileToUpload != null) fileToUpload.close();
}