下载具有多个连接的文件

时间:2016-12-19 20:48:54

标签: java multithreading sockets

您好我想用 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();
}

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

  • 获取a.dat的0-99个字节并将其放入a.dat.part1
  • 获取100.d99字节的a.dat并将其放入a.dat.part1
  • 获取200.299字节的a.dat并将其放入a.dat.part1

1 个答案:

答案 0 :(得分:2)

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

  1. 启动HEAD类型的初始请求,仅获取我文件的Content-Length标题,而不是其实际内容。
  2. 然后根据Content-Length,为每个GET类型的线程启动一个请求,并正确设置HTTP标头RandomAccessFile以获取文件的子部分,知道{ {1}}将提供Range: bytes=0-99个第一个字节。请注意,例外的HTTP代码将是100而不是206,表示您收到了部分内容。

  3. 然后最后使用setLength(long newLength)重建文件,以便能够在给定位置写入文件的内容,因为知道您可以依靠http://gatling.io/docs/1.5.6/user_documentation/tutorial/advanced_usage.html创建一个带有目标大小,以便能够使用200的专用实例为每个线程同时写入文件的内容。