【问题标题】:download file with multiple connections下载具有多个连接的文件
【发布时间】:2017-05-04 23:41:39
【问题描述】:

您好,我想用 multi java.net.Socket 的下载 一个文件。 我可以通过基本 GET 请求获取文件:

Socket socket = new Socket(serverName, 80);
DataOutputStream bw = new DataOutputStream(socket.getOutputStream());
bw.writeBytes("GET " + requestFileName + " HTTP/1.1\r\n");
bw.writeBytes("Host: " + serverName + ":80\r\n\r\n");
bw.flush();

DataInputStream in = new DataInputStream(socket.getInputStream());

OutputStream dos = new FileOutputStream(indexFileName);
byte[] buffer = new byte[2048];
while ((count = in.read(buffer)) != -1) {
    dos.write(buffer, 0, count);
    dos.flush();
}
dos.close();
socket.close();

这很好用,但还不够,因为我希望使用多插座。 我可以通过请求 HEAD 获得 Header,所以我只能获得 Content-Length 现在我的计划是使用此代码创建线程。例如,如果我想下载一个有 3 个线程的文件;我将 Content-Length 除以 3 并用 3 个三线程下载。 (0-99) + (100-199) + (200-299) = 300 对于 300 个字节 然后我将加入部分,但我找不到并行文件下载的方法。我只需要更改以下部分吗?

while ((count = in.read(buffer)) != -1) {
    dos.write(buffer, 0, count);
    dos.flush();
}

或者尝试从文件大小范围的服务器请求? 例如

  • 获取0-99字节的a.dat并放入a.dat.part1
  • 获取 100-199 字节的 a.dat 并放入 a.dat.part1
  • 获取 200-299 字节的 a.dat 并将其放入 a.dat.part1

【问题讨论】:

  • 这并没有你想象的那么重要。网络不是多线程的。注意不要在循环内冲洗。

标签: java multithreading sockets


【解决方案1】:

假设目标 HTTP 服务器支持它,如果我是你,我会:

  1. 启动HEAD 类型的初始请求以仅获取我的文件的标头,例如Content-Length,而不是其实际内容。
  2. 1234563 987654329@ 第一个字节。请注意,例外的 HTTP 代码将是 206 而不是 200,表示您收到了部分内容。
  3. 然后最后使用RandomAccessFile重建文件以便能够在给定位置写入文件内容,知道可以依赖setLength(long newLength)创建一个目标大小的空文件按顺序能够为每个线程使用RandomAccessFile 的专用实例同时写入文件的内容。

【讨论】:

  • 您还需要在多个线程之间同步对文件的访问——假设每个线程都在编写自己的部分(否则,您不妨使用FileOutputStream)。也就是说,如果您有一个文件实例,那么将只有一个文件指针。每个线程将执行seek 来设置文件偏移量,然后是write。在多个线程之间交错这些操作是不行的。
  • 非常感谢它的工作,还有 1 个问题,我只下载文本文件,我真的需要使用 RandomAccessFile,或者我可以通过字符串 concat 将部分内容放在一个文件中吗?跨度>
  • 是的,仍然需要 #1 通过将文件内容存储为字节(如二进制文件)和 #2 避免将整个文件的内容保存到内存中来避免管理编码,这可能导致 OOME
  • 顺便说一句 @NicolasFilotto 是否有任何 GET 命令只能获取正文部分。我只能使用 HEAD 命令获取标题,是否有像 BODY 这样的命令。因为我将拆分部分与 RandomAccessFile 类放在一起,但它也将标题信息放入文件中(例如:如果我用 3 个线程下载文件,我在文件中得到 3 个标题信息)或者我需要在处理输入时手动消除它们流。
  • AFAIK no 没有这样的请求,需要标题来描述正文内容
猜你喜欢
  • 1970-01-01
  • 2023-03-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多