我正在嘗試在我的Android應用程序中使用HttpUrlConnection
在AsyncTask
中從網絡讀取文件。爲什麼BufferedInputStream每次最多讀取2048個字節?
雖然我注意到文件下載的工作速度比它應該慢一點,因爲我使用的網絡速度更快。
所以我檢查發現,BufferedInputStream
對象每次最多隻能讀取2048個字節。沒有我設置的緩衝區大小。即使BufferedInputStream
的內部默認緩衝區大小也是8192字節。
我在這裏添加我的代碼以供參考。
private class DownloadFileTask extends AsyncTask<String, Integer, String> {
@Override
protected String doInBackground(String... params) {
HttpURLConnection connection = null;
BufferedInputStream input = null;
OutputStream output = null;
int lengthOfFile;
int totalBytesDownloaded = 0;
int count;
final int bufferSize = 8 * 1024; // 8KB
try {
// Create the URL
URL url = new URL(params[0]);
// Open connection
connection = (HttpURLConnection) url.openConnection();
// Get the file length
lengthOfFile = connection.getContentLength();
// Input stream to read file - with bufferSize buffer
input = new BufferedInputStream(connection.getInputStream(), bufferSize);
if (isCancelled()) {
return null;
}
// Output stream to write file
File parentFile = TestUtil.getStorageDir(getApplicationContext(),Constants.EXTRA_DIRECTORY_NAME_TEST_MEDIA);
File file = new File(parentFile.getAbsolutePath() + "/" + "zipFile");
if (!file.exists()) {
file.getParentFile().mkdirs();
}
// Create the file o/p stream
output = new FileOutputStream(file.getAbsolutePath());
// Create the buffer o/p stream for performance
BufferedOutputStream bos = new BufferedOutputStream(output, bufferSize);
// Buffer
byte data[] = new byte[bufferSize];
while ((count = input.read(data, 0, bufferSize)) != -1 && !isCancelled()) {
// Increase the total bytes downloaded
totalBytesDownloaded += count;
Log.d("DEBUG_LOG","total bytes read : " + count + " buffer size : " + data.length);
// Write the data to the o/p buffer
bos.write(data, 0, count);
}
// Publish update again since the loop may have skipped the last publish update
publishProgress(totalBytesDownloaded, lengthOfFile);
// Flush the o/p stream
output.flush();
return file.getAbsolutePath();
} catch (SocketException | SocketTimeoutException e) {
handler.sendEmptyMessage(Constants.CASE_INTERNET_FAILURE);
Log.e("DEBUG_LOG", e);
} catch (IOException e) {
Log.e("DEBUG_LOG","Error: " + e.getMessage());
} finally {
// closing streams
if (output != null) {
try {
output.close();
} catch (IOException e) {
AMLog.e(e);
}
}
if (input != null) {
try {
input.close();
} catch (IOException e) {
AMLog.e(e);
}
}
if (connection != null) {
connection.disconnect();
}
}
return null;
}
@Override
protected void onProgressUpdate(Integer... values) {
int percentage = (values[0] * 100)/values[1] ;
textDownloadSizeMb.setText(String.format(getString(R.string.label_download_mb), String.valueOf(values[0]), String.valueOf(values[1])));
textDownloadPercent.setText(String.format(Locale.getDefault(), "%s%s", percentage, " %"));
progressBar.setMax(values[1]);
progressBar.setProgress(values[0]);
}
@Override
protected void onPostExecute(String value) {
}
}
這裏是日誌的一部分,顯示讀出的數據是從來沒有大於2048個字節,而緩衝器大小是8192個字節。
total bytes read : 1748 buffer size : 8192
total bytes read : 2048 buffer size : 8192
total bytes read : 2048 buffer size : 8192
total bytes read : 2048 buffer size : 8192
total bytes read : 1988 buffer size : 8192
我試過多個大於2048的緩衝區大小,但沒有任何東西似乎改變了閱讀速率。
這是什麼原因?我可以更改它以獲取指定緩衝區大小的數據嗎?
你確定源代碼提供足夠的連續字節來讀取它們,因爲? 'read'的JavaDoc明確指出何時中止讀取更多內容,是否調試過它來檢查哪些檢查失敗? – Tom
我嘗試了不同的來源,所以不確定它是否受限於來源。我沒有嘗試在讀取方法內部進行調試。 –