1

大きなファイルを小さな部分に分けて別々に送りたいのですが。ヘダー「Range」を使用しようとしましたが、「org.apache.http.client.NonRepeatableRequestException:繰り返し不可能なリクエストエンティティでリクエストを再試行できません」というメッセージが表示されました。

// create authenticate client
DefaultHttpClient client = new DefaultHttpClient();

// create HTTP put with the file
HttpPut httpPut = new HttpPut(url);
final File recordingFile = new File(mDir, mName);
long fileLength = recordingFile.length();
for (int i=0; i < fileLength; i += 4096) {
    int length = Math.min(4096, (int)recordingFile.length() - i);
    InputStreamEntity entity = new InputStreamEntity(inputStream, length);
    httpPut.setEntity(entity);
    httpPut.addHeader("Connection", "Keep-Alive");
    httpPut.addHeader("Range", "bytes=" + i + "-" + (i + length));

    // Execute
    HttpResponse res = client.execute(httpPut);
    int statusCode = res.getStatusLine().getStatusCode();
}

(「Range」の代わりに)「Content-Range」ヘッダーも試しましたが、同じ例外が発生しました。

httpPut.addHeader("Content-Range", "bytes=" + i + "-" + (i + length) + "/" + fileLength);
httpPut.addHeader("Accept-Ranges", "bytes");
4

1 に答える 1

1

4096 ビットの倍数を繰り返し送信します。たとえば、最初の 2 つの手順を実行してみましょう: i = 0 送信範囲 0 ~4096 i = 4096 送信範囲4096 ~ 8192。

次の行を修正します。

for (int i=0; i <= fileLength; i += 4097) {
    int length = Math.min(4096, (int)recordingFile.length() - i + 1);
    /*...*/
}

そしてそれはうまくいくはずです。

更新: 問題は、何らかの理由 (認証の失敗など) で同じチャンクを再送信しようとすることである可能性があります。この場合、入力ストリームは既に消費されています。次のように、InputStreamEntity の代わりに ByteArrayEntity を使用してみてください。

ByteArrayInputStream bis = new ByteArrayInputStream(recordingFile);
for (int i=0; i <= fileLength; i += 4097) {
    int length = Math.min(4096, (int)recordingFile.length() - i + 1);
    byte[] bytes = new byte[length];
    bis.read(bytes);
    ByteArrayEntity entity = ByteArrayEntity(bytes);
    /*...*/
}
于 2012-05-23T15:26:15.470 に答える