JAVA HttpURLConnection I / O不工作

时间:2014-04-04 19:34:22

标签: java multithreading file-io inputstream httpurlconnection

你好我尊敬的老年人:)

我的目标:通过在Java中使用多线程来下载URL资源,即使用URL中的多线程,即将单个文件下载到多个部分(非常类似于IDM的工作方式)&在下载结束时,将所有这些内容合并为1个最终文件。

技术使用: Java,RandomAccessFile,MultiThreading,InputStreams

问题: 文件已经下载了精确的KB大小,我已多次检查,但最终文件已损坏。例如,如果我下载一个图像,它会有点模糊,如果我下载.exe,它下载很好但是当我运行.exe文件时,它说"媒体损坏,重试下载"。

这是我的主代码,我用它来调用带有参数的线程类,例如fileName,连接的起始范围和结束范围,以及每个将分别更新自己的线程的JProgressBar

public void InitiateDownload()
{
    HttpURLConnection uc = (HttpURLConnection) url.openConnection();
    uc.connect();
    long fileSize = uc.getContentLengthLong();
    System.out.println("File Size = "+ fileSize );
    uc.disconnect();


    chunkSize = (long) Math.ceil(fileSize/6);

    startFrom = 0;
    endRange = (startFrom + chunkSize) - 1;

    Thread t1 = new MyThread(url, fileName, startFrom, endRange, progressBar_1);
    t1.start();
    //-----------------------------------------

    startFrom += chunkSize;
    endRange = endRange + chunkSize;
    System.out.println("Part 2 :: Start = " + startFrom + "\tEnd To = " + endRange );

    Thread t2 = new MyThread(url, fileName, startFrom, endRange, progressBar_2);
    t2.start();
    //-----------------------------------------
    //..
    //..
    //..
    //-----------------------------------------
    startFrom += chunkSize;
    long temp = endRange + chunkSize;
    endRange = temp + (fileSize - temp);    //add any remaining bits, that were rounded off in division

    Thread t6 = new MyThread(url, fileName, startFrom, endRange, progressBar_6);
    t6.start();
    //-----------------------------------------
}

以下是 MyThread 类的 run()函数:

public void run() {

    Thread.currentThread().setPriority(MAX_PRIORITY);

    System.setProperty("http.proxyHost", "192.168.10.50");
    System.setProperty("http.proxyPort", "8080");   

    HttpURLConnection uc = null;
    try  {

        uc = (HttpURLConnection) url.openConnection();

        uc.setRequestProperty("Range", "bytes="+startFrom+"-"+range);
        uc.connect();
        fileSize = uc.getContentLengthLong();

        inStream = uc.getInputStream();

        int[] buffer = new int[ (int) totalDownloadSize ];

        file.seek(startFrom);   //adjusted start of file

这就是我认为问题在哪里

run()继续......

for(int i = 0 ; i < totalDownloadSize; i++)
        {
            buffer[i] = inStream.read();
            file.write(buffer[i]);

            //Updating Progress bars
            totalDownloaded = totalDownloaded + 1;
            int downloaded = (int) (100 * ( totalDownloaded/ (float) totalDownloadSize)) ;
            progressbar.setValue(  downloaded );

        }


        System.err.println( Thread.currentThread().getName() + "'s download is Finished!");
        uc.disconnect();
    }
    catch(IOException e) {
        System.err.println("Exception in " + Thread.currentThread().getName() + "\t Exception = " + e );

    }
    finally {
        try {
            file.close();
            if(inStream!=null)
                inStream.close();

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}   

}

现在文件已经完整下载,但正如我所说,其中一小部分已损坏。 立即, 如果我用for loop循环替换while,问题就完全解决了。

int bytesRead = 0;
        byte[] buffer = new byte[ (int) totalDownloadSize ];

        file.seek(startFrom);   //adjusted start of file

        while( (bytesRead = inStream.read(buffer) ) != -1 ) {

            file.write(buffer, 0, bytesRead);

        }

但是我需要for循环测量每个线程下载多少文件&amp;我想升级各种各样的线索。

请帮我解决for循环逻辑。

如果您可以建议我如何在while循环内升级Jprogressbars。我似乎无法找到一种方法来量化线程下载了多少文件...

我花了很多时间&amp;我现在非常累...

1 个答案:

答案 0 :(得分:1)

您可以使用有效的while循环,然后跟踪读取的总字节数,如下所示:

int totalRead = 0;
while ((bytesRead = inStream.read(buffer)) != -1) {
    totalRead += bytesRead;
    file.write(buffer, 0, bytesRead);

    progressBar.setValue((int)(totalRead / (double) totalDownloadSize));
}

请记住for (a; b; c) { ... }等于a; while (b) { c; ... }