【问题标题】:Java multiple connections downloading fileJava多连接下载文件
【发布时间】:2010-04-23 19:03:52
【问题描述】:

我想在下面的代码中添加多个连接,以便能够更快地下载文件。有人可以帮助我吗?提前致谢。

public void run() {
    RandomAccessFile file = null;
    InputStream stream = null;

    try {
        // Open connection to URL.
        HttpURLConnection connection =
                (HttpURLConnection) url.openConnection();

        // Specify what portion of file to download.
        connection.setRequestProperty("Range",
                "bytes=" + downloaded + "-");

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

        // Make sure response code is in the 200 range.
        if (connection.getResponseCode() / 100 != 2) {
            error();
        }

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

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

        // Open file and seek to the end of it.
        file = new RandomAccessFile("C:\\"+getFileName(url), "rw");
        file.seek(downloaded);

        stream = connection.getInputStream();
        while (status == DOWNLOADING) {
            /* Size buffer according to how much of the
            file is left to download. */
            byte buffer[];
            if (size - downloaded > MAX_BUFFER_SIZE) {
                buffer = new byte[MAX_BUFFER_SIZE];
            } else {
                buffer = new byte[size - downloaded];
            }

            // Read from server into buffer.
            int read = stream.read(buffer);
            if (read == -1) {
                break;
            }

            // Write buffer to file.
            file.write(buffer, 0, read);
            downloaded += read;
            stateChanged();
        }

        /* Change status to complete if this point was
        reached because downloading has finished. */
        if (status == DOWNLOADING) {
            status = COMPLETE;
            stateChanged();
        }
    } catch (Exception e) {
        error();
    } finally {
        // Close file.
        if (file != null) {
            try {
                file.close();
            } catch (Exception e) {
            }
        }

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

【问题讨论】:

  • 您了解您已有的代码吗?因为它看起来非常独立,您需要做的就是创建多个实例并将它们传递给线程池。
  • 还有一个更基本的问题:为什么你认为添加多个连接会让你下载得更快?除非您的服务器正在主动限制吞吐量,否则您已经使用接近满的管道。
  • @Anon:这是一个常见的技巧。当与服务器的 RTT 无法保持管道满时,它有助于建立更多连接(无论带宽如何,每个 RTT 的最大接收器窗口为 1 个)。当您在某处遇到拥塞时,它也会有所帮助,因为 TCP 会尝试为每个 连接 分配公平的份额。更多连接,更多共享,更多带宽。但是,您不太可能随着连接数的增加而线性增加。

标签: java file connection download


【解决方案1】:

你可以使用线程。

将用于下载和更新 RandomAccessFile 的代码放在 Thread/Runnable 中并启动它的多个实例。

使用全局计数器(同步访问)来跟踪有多少线程完成下载,并让主线程等到所有线程都增加了计数器后再关闭文件。

确保同步所有对 RandomAccessFile 的访问,以便线程 A 在线程 B 正在写入文件的另一部分时不能调用 seek(somePosition)

【讨论】:

  • 与其在单个RandomAccessFile上同步,不如给每个线程自己的文件,让操作系统在磁盘缓冲区管理同步。
【解决方案2】:

确保你描述你想出的东西。多个线程的开销以及它们之间的协调可能会使您的代码变慢。 除非你确定这是一个瓶颈,否则不要这样做,代码复杂度会增加,调试也很重要。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-03-20
    • 2017-05-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-04
    相关资源
    最近更新 更多