我正在尝试将文件上传到REST API from Egnyte如果我不使用setFixedLengthStreamingMode(...),文件上传时不会出现异常,当我使用setFixedLengthStreamingMode(...)时我会进入而IO / SSL异常 - >破管。
为什么我需要这个? 由于HTTURLConnection的文档表明你没有设置内容长度或使用setChunkedStreamingMode()然后整个文件将缓存在客户端的内存中,然后发送它不好,因为如果文件太大我可以得到一个OOM例外。你看到我的代码中缺少什么东西吗?
private Integer doFileUpload(final String urlServer, final String pathToOurFile) {
HttpURLConnection connection = null;
DataOutputStream outputStream = null;
FileInputStream fileInputStream = null;
String lineEnd = "\r\n";
String twoHyphens = "--";
String boundary = "*****";
int bytesRead, fileLength, bufferSize;
final int fileSize;
byte[] buffer;
int maxBufferSize = 1 * 1024 * 1024;
try {
File file = new File(pathToOurFile);
fileInputStream = new FileInputStream(file);
URL url = new URL(urlServer);
connection = (HttpURLConnection) url.openConnection();
String[] payload = { twoHyphens + boundary + lineEnd,
"Content-Disposition: form-data; name=\"uploadedfile\";filename=\"" + pathToOurFile + "\"" + lineEnd, lineEnd, lineEnd,
twoHyphens + boundary + twoHyphens + lineEnd };
int payloadLength = 0;
for (String string : payload) {
payloadLength += string.getBytes("UTF-8").length;
}
Logger.d(TAG, "payload length: " + payloadLength);
fileLength = fileInputStream.available();
Logger.d(TAG, "bytes: " + fileLength);
// Not working:
// connection.setFixedLengthStreamingMode(fileLength + payloadLength);
fileSize = fileLength;
// Allow Inputs & Outputs
connection.setDoInput(true);
connection.setDoInput(true);
connection.setUseCaches(false);
connection.setReadTimeout(5000);
connection.setConnectTimeout(5000);
connection.setRequestProperty("Authorization", "Bearer " + mToken);
// Enable POST method
connection.setRequestMethod(HttpPost.METHOD_NAME);
// connection.setRequestProperty("Connection", "Keep-Alive");
connection.setRequestProperty("Connection", "close");
// This header doesn't count to the number of bytes being sent.
connection.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);
// String mimeType = Utils.getMimeType(file.getName());
// connection.setRequestProperty("Content-Type", mimeType);
connection.connect();
outputStream = new DataOutputStream(connection.getOutputStream());
outputStream.writeBytes(payload[0]);
outputStream.writeBytes(payload[1]);
outputStream.writeBytes(payload[2]);
bufferSize = Math.min(fileLength, maxBufferSize);
buffer = new byte[bufferSize];
// Read file
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
final int updateIntervalMilliseconds = 500; // update the UI 2 times a second
boolean stopUploading = (FileState.UPLOADING != mFileInfo.getState() || isCancelled());
long totalBytesRead = 0;
long lastProgressTime = 0;
while (bytesRead > 0 && !stopUploading)
{
Logger.d(TAG, "bytes read: " + totalBytesRead);
stopUploading = (FileState.UPLOADING != mFileInfo.getState() || isCancelled());
if (!stopUploading) {
totalBytesRead += bytesRead;
outputStream.write(buffer, 0, bufferSize);
fileLength = fileInputStream.available();
bufferSize = Math.min(fileLength, maxBufferSize);
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
// send a progress update event in regular intervals
long now = System.currentTimeMillis();
if (now - lastProgressTime > updateIntervalMilliseconds) {
lastProgressTime = now;
final int percentCompleted = (int) ((totalBytesRead * 100) / fileSize);
if (!stopUploading && mFileInfo.getProgress() != percentCompleted) {
mFileInfo.sendEvent(FileEvent.UPLOAD_PROGRESS, percentCompleted);
}
}
}
}
outputStream.writeBytes(payload[3]);
outputStream.writeBytes(payload[4]);
// Responses from the server (code and message)
int serverResponseCode = connection.getResponseCode();
if (serverResponseCode == HttpStatus.SC_OK || serverResponseCode == HttpStatus.SC_CREATED) {
return JBError.JBERR_SUCCESS;
} else {
return serverResponseCode;
}
} catch (SocketTimeoutException e) {
//applayExponentialBackoff(n);
Log.e(TAG, "SocketTimeoutException");
return JBError.JBERR_NO_NETWORK;
} catch (UnknownHostException e) {
Log.e(TAG, "UnknownHostException");
return JBError.JBERR_NO_NETWORK;
} catch (SocketException e) {
Log.e(TAG, "SocketException");
return JBError.JBERR_NO_NETWORK;
} catch (IOException e) {
Log.e(TAG, "IOException");
e.printStackTrace();
return JBError.JBERR_FAILED;
} catch (Exception ex) {
Log.e(TAG, "Exception");
ex.printStackTrace();
return JBError.JBERR_FAILED;
} finally {
if (connection != null) {
connection.disconnect();
}
try {
if (fileInputStream != null) {
fileInputStream.close();
}
if (outputStream != null) {
outputStream.flush();
outputStream.close();
}
} catch (IOException e) {
Log.e(TAG, "IOException");
e.printStackTrace();
}
}
}
答案 0 :(得分:1)
内容长度计算得当吗? 如果您不确定尝试使用固定长度使用分块模式。 对于android,它类似于setChunkedStreamingMode(int chunkLength)。