使用多线程在Java中下载文件

贝扎德·哈萨尼(Behzad Hassani)

我正在使用类似于IDM的下载器,因此我已阅读了有关帖子。并且已经实现了我的第一步代码。

这是下载程序类的代码:

package download.manager;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.channels.ReadableByteChannel;
import java.util.logging.Level;
import java.util.logging.Logger;


public class Downloader implements Runnable{

    private String url;
    private int num;
    private long start;
    private long end;
    ReadableByteChannel rbc;

    public Downloader(String url, int num, long start, long end, ReadableByteChannel rbc) {
        this.url = url;
        this.num = num;
        this.start = start;
        this.end = end;
        this.rbc = rbc;
    }        

    @Override
    public void run() {
        download();
    }

    private void download(){
        try {
            System.out.println(num + " is executing");
            URL file = new URL(url);
            FileOutputStream stream = new FileOutputStream("tmp"+num);                        
            stream.getChannel().transferFrom(rbc, start, end);
        } catch (MalformedURLException ex) {
            Logger.getLogger(Downloader.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(Downloader.class.getName()).log(Level.SEVERE, null, ex);
        }

    }

}

这是我的主要功能:

package download.manager;

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author Behzad
 */
public class DownloadManager {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {

        URL file = null;
        ReadableByteChannel rbc = null;
        try {                       
            String url = "http://dl1.video.varzesh3.com/video/clip93/12/video/havashi/top5_save_derby_dortmond.mp4";
            file = new URL(url);
            rbc = Channels.newChannel(file.openStream());
            int size = file.openConnection().getContentLength(); 
            ExecutorService pool = Executors.newFixedThreadPool(4);
            int partSize = size / 4;
            pool.submit(new Downloader(url, 1, 0, partSize, rbc));
            pool.submit(new Downloader(url, 2, partSize, partSize, rbc));
            pool.submit(new Downloader(url, 3, 2 * partSize, partSize, rbc));
            pool.submit(new Downloader(url, 4, 3 * partSize, partSize, rbc));            
            pool.shutdown();
            pool.awaitTermination(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
        } catch (MalformedURLException | InterruptedException ex) {
            Logger.getLogger(DownloadManager.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(DownloadManager.class.getName()).log(Level.SEVERE, null, ex);
        }



    }

}

但是,当我运行此代码时,下载程序仅下载文件的第一部分。如您在图片中看到的

在此处输入图片说明

我该怎么办?

这是更新的下载方法:

private void download(){
        try {
            System.out.println(num + " is executing");
            URL file = new URL(url);
            ReadableByteChannel rbc = Channels.newChannel(file.openStream());
            FileOutputStream stream = new FileOutputStream("tmp"+num);                        
            stream.getChannel().transferFrom(rbc, start, end);
        } catch (MalformedURLException ex) {
            Logger.getLogger(Downloader.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(Downloader.class.getName()).log(Level.SEVERE, null, ex);
        }

    }
彼得·劳瑞

transferTo 是线程安全的,因此您一次只能从一个线程调用它。

如果要一次读取文件的多个部分,则服务器必须支持此功能,并且需要为要下载的文件的每个部分提供流。

有关如何读取文件部分的信息

使用HTTP请求下载文件的一部分

使用HTTP读取文件的第一部分

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

使用多线程在Java中下载文件

来自分类Dev

在python中使用多线程下载文件

来自分类Dev

使用UpdatePanel从流中下载文件

来自分类Dev

使用JavaScript在Safari中下载文件

来自分类Dev

如何使用Python 2.7通过HTTP使用多线程下载文件(异步下载)

来自分类Dev

用于在Python中下载NCBI文件的多线程

来自分类Dev

python中的多处理/多线程下载文件

来自分类Dev

python中的多处理/多线程下载文件

来自分类Dev

在SPA中下载文件

来自分类Dev

在Mojolicious中下载文件

来自分类Dev

在DoFn中下载文件

来自分类Dev

在 r 中下载文件

来自分类Dev

如何使用Selenium在点击事件中下载文件?

来自分类Dev

使用外部资源的URL在Laravel中下载文件

来自分类常见问题

使用Response :: download在laravel中下载文件

来自分类Dev

如何使用phpstorm在ftp中下载文件

来自分类Dev

如何使用Liferay在portlet中下载文件或InpuStream?

来自分类Dev

使用AJAX调用在javascript中下载文件

来自分类Dev

使用JavaRx / rx-mongodb在Grails中下载文件

来自分类Dev

无法使用FileTransfer在Cordova和Ionic中下载文件

来自分类Dev

多线程文件传输/使用javascript下载

来自分类Dev

多线程Java下载器正在下载损坏的文件?

来自分类Dev

在Struts 2中下载文件

来自分类Dev

如何在Watir中下载文件?

来自分类Dev

如何在webView中下载文件?

来自分类Dev

无法在UpdatePanel中下载文件

来自分类Dev

如何在Codeigniter中下载文件?

来自分类Dev

在Android Webview中下载文件

来自分类Dev

避免在Python Urlopen中下载文件