我的代码有三个部分--
与我以前实现可恢复上传的RetryHttpInitializerWrapper相同,它的工作方式与预期的一样,它的上传以10-10 MB块为单位。请建议我错过了什么,因为对于单个请求,它可以正常工作,但是对于可恢复的下载,它的能力。我只是在下载的时候断开了我的互联网,以测试可恢复的东西,但当我再次连接时,它会恢复下载。
public void downloadToOutputStream(String bucketName, String objectName, OutputStream data)
throws IOException, GeneralSecurityException {
GoogleCredential credential = GoogleCredential.getApplicationDefault();
if (credential.createScopedRequired()) {
credential = credential.createScoped(StorageScopes.all());
}
HttpTransport httpTransport = GoogleNetHttpTransport.newTrustedTransport();
// custom HttpRequestInitializer for automatic retry upon failures.
HttpRequestInitializer httpRequestInitializer = new RetryHttpInitializerWrapper(credential);
GenericUrl requestUrl = new GenericUrl(
"https://www.googleapis.com/storage/v1/b/" + bucketName + "/o/" + objectName);
MediaHttpDownloader downloader = new MediaHttpDownloader(httpTransport, httpRequestInitializer);
downloader.setProgressListener(new CustomDownloadProgressListener());
downloader.download(requestUrl, data);
}
public class RetryHttpInitializerWrapper implements HttpRequestInitializer {
private static final Logger LOG = Logger.getLogger(RetryHttpInitializerWrapper.class.getName());
private final Credential wrappedCredential;
private final Sleeper sleeper;
private static final int MILLIS_PER_MINUTE = 60 * 1000;
/**
* A constructor using the default Sleeper.
*
* @param wrappedCredential
* the credential used to authenticate with a Google Cloud
* Platform project
*/
public RetryHttpInitializerWrapper(Credential wrappedCredential) {
this(wrappedCredential, Sleeper.DEFAULT);
}
/**
* A constructor used only for testing.
*
* @param wrappedCredential
* the credential used to authenticate with a Google Cloud
* Platform project
* @param sleeper
* a user-supplied Sleeper
*/
RetryHttpInitializerWrapper(Credential wrappedCredential, Sleeper sleeper) {
this.wrappedCredential = Preconditions.checkNotNull(wrappedCredential);
this.sleeper = sleeper;
}
/**
* Initialize an HttpRequest.
*
* @param request
* an HttpRequest that should be initialized
*/
public void initialize(HttpRequest request) {
request.setReadTimeout(2 * MILLIS_PER_MINUTE); // 2 minutes read
// timeout
final HttpUnsuccessfulResponseHandler backoffHandler = new HttpBackOffUnsuccessfulResponseHandler(
new ExponentialBackOff()).setSleeper(sleeper);
request.setInterceptor(wrappedCredential);
request.setUnsuccessfulResponseHandler(new HttpUnsuccessfulResponseHandler() {
public boolean handleResponse(final HttpRequest request, final HttpResponse response,
final boolean supportsRetry) throws IOException {
if (wrappedCredential.handleResponse(request, response, supportsRetry)) {
// If credential decides it can handle it, the return
// code or message indicated
// something specific to authentication, and no backoff
// is desired.
return true;
} else if (backoffHandler.handleResponse(request, response, supportsRetry)) {
// Otherwise, we defer to the judgement of our internal
// backoff handler.
System.out.println("Retrying " + request.getUrl().toString());
return true;
} else {
return false;
}
}
});
request.setIOExceptionHandler(
new HttpBackOffIOExceptionHandler(new ExponentialBackOff()).setSleeper(sleeper));
}
}
public class CustomDownloadProgressListener implements MediaHttpDownloaderProgressListener {
public void progressChanged(MediaHttpDownloader downloader) {
switch (downloader.getDownloadState()) {
case MEDIA_IN_PROGRESS:
System.out.println(downloader.getProgress());
break;
case MEDIA_COMPLETE:
System.out.println("Download is complete!");
}
}
}发布于 2019-07-08 15:18:57
我不会在这里发布任何代码,但我最近成功地使用Range头从Google获得了一个可恢复的下载。
假设我有一个570字节的文本文件,以:
The next morning Hanna distracts Dieter如果我发送一个带有值Range的bytes=0-21头,那么我将返回The next morning Hanna。
如果我发送一个带有值Range的bytes=3-32头,那么我将返回next morning Hanna distracts。
(注意:Range头使用包含的间隔。)
除非我的块大小大于文件大小,并且不存在某些网络错误,否则我总是希望响应包含一个Content-Range头,指示我刚才下载的字节范围以及文件的总大小。例如,对我的第一个请求的响应将包含Content-Range: bytes 0-21/570,因此我的下一个请求的Range起始位置为字节22,例如bytes=22-43。
https://stackoverflow.com/questions/54112631
复制相似问题