在java中恢复http文件下载

在java中恢复http文件下载,java,android,http,download,Java,Android,Http,Download,在这段代码中,我尝试恢复下载。目标文件为20MB。但当我停止下载10mb,然后继续下载时,我得到的文件大小为30MB。它似乎继续写入文件,但不能部分从服务器下载。Wget-c非常适合这个文件。如何恢复文件下载?签出。如果wget正在工作,那么服务器显然支持恢复下载。看起来您没有设置上述链接的可接受答案中提到的If Range标题。即加上: URL url = new URL("http://download.thinkbroadband.com/20MB.zip"); URLConnectio

在这段代码中,我尝试恢复下载。目标文件为20MB。但当我停止下载10mb,然后继续下载时,我得到的文件大小为30MB。它似乎继续写入文件,但不能部分从服务器下载。Wget-c非常适合这个文件。如何恢复文件下载?

签出。如果wget正在工作,那么服务器显然支持恢复下载。看起来您没有设置上述链接的可接受答案中提到的
If Range
标题。即加上:

URL url = new URL("http://download.thinkbroadband.com/20MB.zip");

URLConnection connection = url.openConnection();
File fileThatExists = new File(path); 
OutputStream output = new FileOutputStream(path, true);
connection.setRequestProperty("Range", "bytes=" + fileThatExists.length() + "-");

connection.connect();

int lenghtOfFile = connection.getContentLength();

InputStream input = new BufferedInputStream(url.openStream());
byte data[] = new byte[1024];

long total = 0;

while ((count = input.read(data)) != -1) {
    total += count;

    output.write(data, 0 , count);
}

这不是我的代码,但它可以工作。

我想您面临的问题是在
url.openConnection()之后调用
url.openStream()

url.openStream()
相当于
url.openConnection().getInputStream()
。因此,您需要两次请求url。特别是第二次,它没有指定range属性。因此,下载总是从一开始就开始


您应该将
url.openStream()
替换为
connection.getInputStream()

,因为问题是用Android标记的: 你试过使用吗。
它可以很好地为您处理所有这些内容。

我有一种方法可以让您的代码正常工作

  • 首先,检查文件是否退出
  • 如果文件存在,请设置连接:

     HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        if(ISSUE_DOWNLOAD_STATUS.intValue()==ECMConstant.ECM_DOWNLOADING){
            File file=new File(DESTINATION_PATH);
            if(file.exists()){
                 downloaded = (int) file.length();
                 connection.setRequestProperty("Range", "bytes="+(file.length())+"-");
            }
        }else{
            connection.setRequestProperty("Range", "bytes=" + downloaded + "-");
        }
        connection.setDoInput(true);
        connection.setDoOutput(true);
        progressBar.setMax(connection.getContentLength());
         in = new BufferedInputStream(connection.getInputStream());
         fos=(downloaded==0)? new FileOutputStream(DESTINATION_PATH): new FileOutputStream(DESTINATION_PATH,true);
         bout = new BufferedOutputStream(fos, 1024);
        byte[] data = new byte[1024];
        int x = 0;
        while ((x = in.read(data, 0, 1024)) >= 0) {
            bout.write(data, 0, x);
             downloaded += x;
             progressBar.setProgress(downloaded);
        }
    
  • 如果文件不存在,请在新文件中进行相同的下载

  • 这个怎么样

    connection.setRequestProperty("Range", "bytes=" + bytedownloaded + "-");
    

    使用
    break以测试代码…;)

    这是我用来下载区块中的文件,并随进度更新UI的内容

    public static void download(DownloadObject object) throws IOException{
        String downloadUrl = object.getDownloadUrl();
        String downloadPath = object.getDownloadPath();
        long downloadedLength = 0;
    
        File file = new File(downloadPath);
        URL url = new URL(downloadUrl);
    
        BufferedInputStream inputStream = null;
        BufferedOutputStream outputStream = null;
    
        URLConnection connection = url.openConnection();
    
        if(file.exists()){
            downloadedLength = file.length();
            connection.setRequestProperty("Range", "bytes=" + downloadedLength + "-");
            outputStream = new BufferedOutputStream(new FileOutputStream(file, true));
    
        }else{
            outputStream = new BufferedOutputStream(new FileOutputStream(file));
    
        }
    
        connection.connect();
    
        inputStream = new BufferedInputStream(connection.getInputStream());
    
    
        byte[] buffer = new byte[1024*8];
        int byteCount;
    
        while ((byteCount = inputStream.read(buffer)) != -1){
            outputStream.write(buffer, 0, byteCount);
            break;
    
        }
    
        inputStream.close();
        outputStream.flush();
        outputStream.close();
    
    }
    
    接口IDownloadCallback{

    /*
     * @param callback = To update the UI with appropriate action
     * @param fileName = Name of the file by which downloaded file will be saved.
     * @param downloadURL = File downloading URL
     * @param filePath = Path where file will be saved
     * @param object = Any object you want in return after download is completed to do certain operations like insert in DB or show toast
     */
    
    public void startDownload(final IDownloadCallback callback, String fileName, String downloadURL, String filePath, Object object) {
        callback.onPreExecute(); // Callback to tell that the downloading is going to start
        int count = 0;
        File outputFile = null; // Path where file will be downloaded
        try {
            File file = new File(filePath);
            file.mkdirs();
            long range = 0;
            outputFile = new File(file, fileName);
            /**
             * Check whether the file exists or not
             * If file doesn't exists then create the new file and range will be zero.
             * But if file exists then get the length of file which will be the starting range,
             * from where the file will be downloaded
             */
            if (!outputFile.exists()) {
                outputFile.createNewFile();
                range = 0;
            } else {
                range = outputFile.length();
            }
            //Open the Connection
            URL url = new URL(downloadURL);
            URLConnection con = url.openConnection();
            // Set the range parameter in header and give the range from where you want to start the downloading
            con.setRequestProperty("Range", "bytes=" + range + "-");
            /**
             * The total length of file will be the total content length given by the server + range.
             * Example: Suppose you have a file whose size is 1MB and you had already downloaded 500KB of it.
             * Then you will pass in Header as "Range":"bytes=500000".
             * Now the con.getContentLength() will be 500KB and range will be 500KB.
             * So by adding the two you will get the total length of file which will be 1 MB
             */
            final long lenghtOfFile = (int) con.getContentLength() + range;
    
            FileOutputStream fileOutputStream = new FileOutputStream(outputFile, true);
            InputStream inputStream = con.getInputStream();
    
            byte[] buffer = new byte[1024];
    
            long total = range;
            /**
             * Download the save the content into file
             */
            while ((count = inputStream.read(buffer)) != -1) {
                total += count;
                int progress = (int) (total * 100 / lenghtOfFile);
                EntityDownloadProgress entityDownloadProgress = new EntityDownloadProgress();
                entityDownloadProgress.setProgress(progress);
                entityDownloadProgress.setDownloadedSize(total);
                entityDownloadProgress.setFileSize(lenghtOfFile);
                callback.showProgress(entityDownloadProgress);
                fileOutputStream.write(buffer, 0, count);
            }
            //Close the outputstream
            fileOutputStream.close();
            // Disconnect the Connection
            if (con instanceof HttpsURLConnection) {
                ((HttpsURLConnection) con).disconnect();
            } else if (con instanceof HttpURLConnection) {
                ((HttpURLConnection) con).disconnect();
            }
            inputStream.close();
            /**
             * If file size is equal then return callback as success with downlaoded filepath and the object
             * else return failure
             */
            if (lenghtOfFile == outputFile.length()) {
                callback.onSuccess(outputFile.getAbsolutePath(), object);
            } else {
                callback.onFailure(object);
            }
        } catch (Exception e) {
            e.printStackTrace();
            callback.onFailure(object);
        }
    }
    
    公共类实体下载进度{

        void onPreExecute(); // Callback to tell that the downloading is going to start
        void onFailure(Object o); // Failed to download file
        void onSuccess(String path, Object o); // Downloaded file successfully with downloaded path
        void showProgress(EntityDownloadProgress entityDownloadProgress); // Show progress
    }
    

    可能与您的代码重复我的应用程序未下载任何内容。lastmodified字符串包含有效日期(2008年5月14日)。可能是什么?您好,'ISSUE_download_STATUS.intValue()'我不了解此值,请给我此值的参考。我预计此代码将无法正常工作。如果(ISSUE_DOWNLOAD_STATUS.intValue()==ECMConstant.ECM_DOWNLOADING)失败,而else{}语句将在“已下载”的位置执行变量未定义。@asiby让我们假设我们都可以编写一点代码,这段代码为您提供了如何解决问题的提示,而不是一个完整的解决方案。嘿,这里@Ceetn,如果您不能提供任何建设性的帮助,那么就压缩它。这里的大多数人都努力提供功能性解决方案。这段代码看起来像是源于它可能工作的地方ing,但是缺少变量声明。我试着使用它,我花了很多时间试图理解它。什么是问题?下载状态和ECMConstat?你可能很清楚。但是你完全错误地认为人们在这里寻求帮助时可以编写代码。如果你使用它,你会有不同的反应d在你的编程课上也是这样。我不明白这个答案怎么会有更多的赞成票,也被接受。很多没有解释的东西,外部引用。常量没有值。在if分支中设置的下载属性值,在else分支中使用。if和else分支是相同的。为什么setDoOutput设置为true?传递了任何POST?相同的缓冲区大小在3个位置使用,没有常数使用。根本没有错误处理。非常感谢。你真的救了我!我遇到了一个类似的问题,你的解决方案非常完美。谢谢你!我搜索了我的问题大约一个小时,而你,先生,你让我很开心,解决了它!非常感谢!谢谢,我会切换到它,下载应该会更多现在,请记住它需要API级别9(Android 2.3)。我不知道这是否是一个问题。2.2几乎已经过时了。除了提供一些代码外,请添加一些文本解释代码工作的原因。@buczek下载文件是标准代码,除了connect.setRequestProperty方法和FileOutputStream的append属性设置为true。这应该是可以接受的答案,因为它是完美地处理进度条的更改。
        void onPreExecute(); // Callback to tell that the downloading is going to start
        void onFailure(Object o); // Failed to download file
        void onSuccess(String path, Object o); // Downloaded file successfully with downloaded path
        void showProgress(EntityDownloadProgress entityDownloadProgress); // Show progress
    }
    
        int progress; // range from 1-100
        long fileSize;// Total size of file to be downlaoded
        long downloadedSize; // Size of the downlaoded file
    
        public void setProgress(int progress) {this.progress = progress;}
    
        public void setFileSize(long fileSize) {this.fileSize = fileSize;}
    
        public void setDownloadedSize(long downloadedSize) {this.downloadedSize = downloadedSize;}
    }