首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >谷歌云可拯救下载未发生

谷歌云可拯救下载未发生
EN

Stack Overflow用户
提问于 2019-01-09 14:43:27
回答 1查看 165关注 0票数 2

我的代码有三个部分--

  • CustomDownloadProgressListener
  • downloadToOutputStream()函数,其中我编写了从云存储下载文件的代码
  • RetryHttpInitializerWrapper是HttpRequestInitializer的包装器,如MediaHttpDownloader类java中所建议的那样,以防响应不良或网络中断。

与我以前实现可恢复上传的RetryHttpInitializerWrapper相同,它的工作方式与预期的一样,它的上传以10-10 MB块为单位。请建议我错过了什么,因为对于单个请求,它可以正常工作,但是对于可恢复的下载,它的能力。我只是在下载的时候断开了我的互联网,以测试可恢复的东西,但当我再次连接时,它会恢复下载。

代码语言:javascript
复制
    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!");
        }
    }
}
EN

回答 1

Stack Overflow用户

发布于 2019-07-08 15:18:57

我不会在这里发布任何代码,但我最近成功地使用Range头从Google获得了一个可恢复的下载。

假设我有一个570字节的文本文件,以:

代码语言:javascript
复制
The next morning Hanna distracts Dieter

如果我发送一个带有值Rangebytes=0-21头,那么我将返回The next morning Hanna

如果我发送一个带有值Rangebytes=3-32头,那么我将返回next morning Hanna distracts

(注意:Range头使用包含的间隔。)

除非我的块大小大于文件大小,并且不存在某些网络错误,否则我总是希望响应包含一个Content-Range头,指示我刚才下载的字节范围以及文件的总大小。例如,对我的第一个请求的响应将包含Content-Range: bytes 0-21/570,因此我的下一个请求的Range起始位置为字节22,例如bytes=22-43

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54112631

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档