在java中恢复http文件下载

POM*_*ATu 56 java android http download

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);
}
Run Code Online (Sandbox Code Playgroud)

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

POM*_*ATu 57

 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);
    }
Run Code Online (Sandbox Code Playgroud)

这不是我的代码,但它有效.

  • 嘿那里@Ceetn,如果你不能给予任何建设性的帮助,那就拉上它吧.这里的大多数人都努力提供功能性解决方案.这个看起来它起源于它可能正在工作的某个地方,但是缺少变量声明.我试图使用它,我花了几分钟试图理解它.什么是ISSUE_DOWNLOAD_STATUS和ECMConstant?你可能很清楚.但是,假设人们可以在这里寻求帮助时可以编码是完全错误的.如果你的老师在你的编程课程中表现得那样,你会有不同的反应. (13认同)
  • 您好,'ISSUE_DOWNLOAD_STATUS.intValue()'我不明白这个值,请给我参考. (7认同)
  • 我不明白这个答案是如何获得更多赞成票并被接受的。很多没有解释的东西,外部参考。常量没有价值。在 if 分支中设置的下载属性值,在 else 分支中使用。if 和 else 分支是一样的。为什么 setDoOutput 设置为 true?任何POST通过?在 3 个地方使用相同的缓冲区大小,没有使用常量。根本没有错误处理。 (4认同)
  • @asiby让我们假设我们都可以编写一些代码,这段代码为您提供了如何解决问题而不是完全修复的提示. (3认同)

小智 17

我猜你所面临的问题是调用url.openStream()url.openConnection().

url.openStream()相当于url.openConnection().getInputStream().因此,您要求两次网址.特别是第二次,它没有指定范围属性.因此,下载始终从头开始.

此时应更换url.openStream()使用connection.getInputStream().


Ank*_*mar 6

这就是我用来分块下载文件的内容 使用进度更新 UI。

/*
 * @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);
    }
}
Run Code Online (Sandbox Code Playgroud)

接口 IDownloadCallback {

    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
}
Run Code Online (Sandbox Code Playgroud)

公共类 EntityDownloadProgress {

    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;}
}
Run Code Online (Sandbox Code Playgroud)