首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >多线程java下载器下载损坏的文件?

多线程java下载器下载损坏的文件?
EN

Stack Overflow用户
提问于 2014-09-24 09:39:19
回答 2查看 754关注 0票数 0

我正在尝试用java制作一个multiThread下载程序。它可以工作,但我下载的文件总是缺少一些字节。

我搜索并找到了许多multiThreaded网络爬虫的例子,但是并不简单,所以有人能告诉我我的方法是否有效吗?

我不知道问题是否在于字节的排序。

我试过BlockingQueue,但没有用

代码语言:javascript
复制
URL url = new URL(mURL);
        final HttpURLConnection conn;
        conn = (HttpURLConnection) url.openConnection();
        conn.setConnectTimeout(10000);
        conn.connect();
        final BufferedInputStream in = new BufferedInputStream(conn.getInputStream());
        final File f = new File("tr.exe");
        if (f.exists()) {
            f.delete();
        }
        // open the output file and seek to the start location
        Thread t1 = new Thread() {
            public void run() {
                try {
                    RandomAccessFile raf = new RandomAccessFile(f, "rw");
                    raf.seek(0);
                    int numRead;
                    int mStartByte = 0;
                    byte data[] = new byte[conn.getContentLength() / 2];
                    while (((numRead = in.read(data, 0, 1024)) != -1) && (mStartByte < conn.getContentLength() / 2)) {
                        // write to buffer
                        raf.write(data, 0, numRead);
                        // increase the startByte for resume later
                        mStartByte += numRead;
                        // increase the downloaded size
                    }
                    raf.close();
                } catch (FileNotFoundException ex) {
                    Logger.getLogger(MyDownloader.class.getName()).log(Level.SEVERE, null, ex);
                } catch (IOException ex) {
                    Logger.getLogger(MyDownloader.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        };
        Thread t2 = new Thread() {
            public void run() {
                try {
                    RandomAccessFile raf = new RandomAccessFile(f, "rw");
                    raf.seek(conn.getContentLengthLong() / 2);
                    int numRead;
                    int mStartByte = conn.getContentLength() / 2;
                    byte data[] = new byte[conn.getContentLength() / 2];
                    while (((numRead = in.read(data, 0, 1024)) != -1) && (mStartByte < conn.getContentLength())) {
                        // write to buffer
                        raf.write(data, 0, numRead);
                        // increase the startByte for resume later
                        mStartByte += numRead;
                        // increase the downloaded size
                    }
                    raf.close();
                } catch (FileNotFoundException ex) {
                    Logger.getLogger(MyDownloader.class.getName()).log(Level.SEVERE, null, ex);
                } catch (IOException ex) {
                    Logger.getLogger(MyDownloader.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        };
        t1.start();
        t2.start();
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-09-24 10:08:11

这是我注意到的第一个问题..。

  • 首先,我会将您的下载/编写代码放在实现Runnable的单独类中,然后使用ExecutorService执行它。
  • byte[] data应该与您正在读取的块大小相同,您已经硬编码为1024。
  • int mStartByte = conn.getContentLength() / 2,如果长度是一个奇数呢?
  • 因为你有两个线程从相同的流读取,你不能保证这一点。第一线程读上半,第二线程读下半。我怀疑它不会适用于2048字节以上的文件。在每次读取迭代中,您都需要知道您要在流中从何处开始,以便您能够找到正确的位置。
票数 0
EN

Stack Overflow用户

发布于 2014-09-24 09:57:50

在我看来,您正在同时写入同一个文件,是的,顺序改变了,您甚至可能会丢失一些字节,现在您应该做的是编写文件的第一个线程的输出,例如'Thread1Output‘和第二个线程到'Thread2Output’,并在最后将两个文件组装到一个文件中,希望它对您有用,祝您好运,对不起,我提供了代码,因为我从来没有创建过一个下载程序=D。

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

https://stackoverflow.com/questions/26013563

复制
相关文章

相似问题

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