【问题标题】:downloading files in java in several parts or segments在java中分几个部分或段下载文件
【发布时间】:2018-06-01 23:10:46
【问题描述】:

我正在尝试以多段方式下载 java 中的文件(即,将其分成几个部分并在单独的线程中并行下载每个部分)但是当我使用下面的代码时,似乎每个线程都在下载整个文件而不是其中的一部分,但是当它完成时,文件被正确下载。

请注意,“downloadedSizeCombined”是所有线程下载的所有字节的总和,ArrayList“downloadedSize”跟踪单个线程下载的字节。

此方法在扩展 SwingWorker 的下载类中。

public Void doInBackground() {
    ExecutorService es = Executors.newCachedThreadPool();
    for (int i = 0; i < MAX_NUMBER_OF_PARTS; i++) {
        int numOfThePart = i;
        es.execute(new Runnable() {
            @Override
            public void run() {
                RandomAccessFile file = null;
                InputStream stream = null;

                try {
                    while (Download.this.getStatus() == WAITINGLIST) {
                        Thread.sleep(1);
                    }
                    // Open connection to URL.
                    HttpURLConnection connection =
                        (HttpURLConnection) url.openConnection();

                    // Specify what portion of file to download.
                    int startByte = numOfThePart * sizeOfFile / MAX_NUMBER_OF_PARTS;
                    int endByte = ((numOfThePart + 1) * sizeOfFile / MAX_NUMBER_OF_PARTS) - 1;
                    if (numOfThePart == MAX_NUMBER_OF_PARTS)
                        endByte = ((numOfThePart + 1) * sizeOfFile / MAX_NUMBER_OF_PARTS);
                    connection.setRequestProperty("Range",
                        "bytes=" + ((startByte + downloadedSize.get(numOfThePart))) + "-" + endByte);

                    // Connect to server.
                    connection.connect();

                    // Check for valid content length.
                    int contentLength = connection.getContentLength();
                    if (contentLength < 1) {
                        System.out.println("1");
                    }

                    /* Set the size for this download if it
                       hasn't been already set. */
                    if (sizeOfFile == -1) {
                        sizeOfFile = contentLength;
                    }

                    file = new RandomAccessFile(new File(s.getCurrentDirectory(), getFileName(url)),
                        "rw");
                    file.seek(startByte + downloadedSize.get(numOfThePart));

                    fileLocation = new File(s.getCurrentDirectory(), getFileName(url));

                    stream = connection.getInputStream();
                    while (status == CURRENT) {
                        file.seek(startByte + downloadedSize.get(numOfThePart));

                        byte buffer[];

                        buffer = new byte[MAX_BUFFER_SIZE];

                        // Read from server into buffer.
                        int read = stream.read(buffer);

                        if (read == -1)
                            break;

                        // Write buffer to file.
                        file.write(buffer, 0, read);
                        downloadedSizeCombined += read;
                        downloadedSize.set(numOfThePart, downloadedSize.get(numOfThePart) + read);

                        publish(numOfThePart);
                        while (status == PAUSED) {
                            Thread.sleep(1);
                        }

                    }

                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    // Close file.
                    if (file != null) {
                        try {
                            file.close();
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }

                    // Close connection to server.
                    if (stream != null) {
                        try {
                            stream.close();
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        });
    }
    return null;
}

提前致谢。

【问题讨论】:

  • 并非每个 http 服务器都支持此代码使用的 "Range: bytes=start-finish" 标头。也许这就是原因? (我也怀疑并行下载是否真的有用,因为典型的服务器只需 1 次下载就可以使连接饱和)
  • 我已经在支持并行下载但没有运气的服务器上对其进行了测试。这是一个项目需求,所以我还是应该实现它。

标签: java multithreading concurrency download


【解决方案1】:

我们不能使用 UDP 连接吗?因此,如果我们使用 DatagramSocket 类,它无论如何都会以数据包的形式发送数据。尝试这个。 很快就会回来..

【讨论】:

    猜你喜欢
    • 2013-05-09
    • 1970-01-01
    • 2015-04-19
    • 2014-12-17
    • 1970-01-01
    • 1970-01-01
    • 2014-06-18
    • 2021-12-24
    • 2019-09-08
    相关资源
    最近更新 更多