我有一个奇怪的问题,我真的会对此有所了解。我有一些代码可以下载各种文件。一些文件返回值为“chunked”的“transfer-encoding”标头,我很确定这是导致我出现问题的原因。
这就是它变得非常奇怪的地方。在我的 Motorolla Droid 上下载 3g 时,使用此编码的文件无法正确下载,因为它在读取所有字节之前完成下载,因此我有一个损坏的文件。但是,在完全相同的手机上使用 WiFi 下载相同的文件就好了。
这听起来像是服务器问题吗?安卓问题?3g问题?我的代码问题?
这是我用来读取响应标头的一些代码:
private void readResponseHeaders(HttpResponse response) throws StopRequest {
Header header = response.getFirstHeader("Content-Disposition");
if (header != null) {
mInfo.mInnerState.mHeaderContentDisposition = header.getValue();
}
header = response.getFirstHeader("Content-Location");
if (header != null) {
mInfo.mInnerState.mHeaderContentLocation = header.getValue();
}
if (mInfo.mMimeType == null) {
header = response.getFirstHeader("Content-Type");
if (header != null) {
mInfo.mMimeType = sanitizeMimeType(header.getValue());
}
}
header = response.getFirstHeader("ETag");
if (header != null) {
mInfo.mInnerState.mHeaderETag = header.getValue();
}
String headerTransferEncoding = null;
header = response.getFirstHeader("Transfer-Encoding");
if (header != null) {
headerTransferEncoding = header.getValue();
}
if (headerTransferEncoding == null) {
header = response.getFirstHeader("Content-Length");
if (header != null) {
mInfo.mInnerState.mHeaderContentLength = header.getValue();
mInfo.mTotalBytes = Long.parseLong(mInfo.mInnerState.mHeaderContentLength);
if (!mFileManager.hasSufficientSpace(mInfo.mTotalBytes, mBasePath)){
throw new StopRequest(ServiceDownloadConstants.STATUS_INSUFFICIENT_SPACE_ERROR, "Not Enough Space");
}
}
} else {
// Ignore content-length with transfer-encoding - 2616 4.4 3
if (ServiceDownloadConstants.LOGVV) {
Log.v(ServiceDownloadConstants.TAG,
"ignoring content-length because of xfer-encoding");
}
}
if (ServiceDownloadConstants.LOGVV) {
Log.v(ServiceDownloadConstants.TAG, "Content-Disposition: " + mInfo.mInnerState.mHeaderContentDisposition);
Log.v(ServiceDownloadConstants.TAG, "Content-Length: " + mInfo.mInnerState.mHeaderContentLength);
Log.v(ServiceDownloadConstants.TAG, "Content-Location: " + mInfo.mInnerState.mHeaderContentLocation);
Log.v(ServiceDownloadConstants.TAG, "Content-Type: " + mInfo.mMimeType);
Log.v(ServiceDownloadConstants.TAG, "ETag: " + mInfo.mInnerState.mHeaderETag);
Log.v(ServiceDownloadConstants.TAG, "Transfer-Encoding: " + headerTransferEncoding);
}
boolean noSizeInfo = mInfo.mInnerState.mHeaderContentLength == null
&& (headerTransferEncoding == null
|| !headerTransferEncoding.equalsIgnoreCase("chunked"));
if (!mInfo.mNoIntegrity && noSizeInfo) {
throw new StopRequest(ServiceDownloadConstants.STATUS_HTTP_DATA_ERROR,
"can't know size of download, giving up");
}
}
这是我用来传输数据的一些代码:
private void transferData(byte[] data, InputStream entityStream) throws StopRequest {
for (;;) {
int bytesRead = readFromResponse( data, entityStream);
if (bytesRead == -1) {
// success, end of stream already reached
handleEndOfStream();
return;
}
writeDataToDestination(data, bytesRead);
mInfo.mInnerState.mBytesSoFar += bytesRead;
/** Update SHA1 if needed **/
if( mInfo.mEnclosure.getHash() != null && mSha1 != null ){
mSha1.update( data, 0, bytesRead );
}
if (ServiceDownloadConstants.LOGVV) {
Log.v(ServiceDownloadConstants.TAG, "downloaded " + mInfo.mInnerState.mBytesSoFar + " for "
+ mInfo.mEnclosure.getUrl());
}
checkPausedOrCanceled();
}
}
编辑 在进一步调试后,即使没有发送“传输编码”标头,我也收到了完全相同的结果,所以看起来我的问题与在 Wifi 上工作一样普遍,但在 3g 上却没有。