java网络传输,一般使用http协议传输,对于一般的下载,我们只需开一个线程即可,但对于下载文件较大,有比较耗时的下载,我们可以使用多线程下载。使用Http的Range头字段指定每条线程从文件的什么位置开始下载,下载到什么位置为止和RandomAccessFile 文件可随机读写操作就比较方便了。网上有许多多线程下载的例子。这是我在学习的过程中学到的,分享给需要学习的同学。关键是conn.setRequestProperty("Range", "bytes=" + startPosition + "-");其它的和平时写法一样,比较简单。
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.URL;
public class DownLoaderTest
{
public static byte[] readStream(InputStream inStream) throws IOException
{
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len = -1;
while ((len = inStream.read(buffer)) != -1)
{
outputStream.write(buffer, 0, len);
}
outputStream.close();
inStream.close();
return outputStream.toByteArray();
}
public void down() throws Exception
{
String urlpath = "http://i2.itc.cn/20130305/2d89_e5380baf_d814_b091_6ca2_9208da28f4dd_1.jpg";
URL url = new URL(urlpath);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(5 * 1000);
conn.setRequestMethod("GET");
int theadSize = 3;
int fileSize = conn.getContentLength(); // 获取文件大小
int block = fileSize / 3 + 1; // 每条线程下载的数量
conn.disconnect();
File file = new File(urlpath.substring(urlpath.lastIndexOf("/") + 1, urlpath.length()));
RandomAccessFile randomFile = new RandomAccessFile(file, "rw");// RandomAccessFile可以指定从什么位置写入数据
randomFile.setLength(fileSize);// 设置文件大小
System.out.println("文件大小"+fileSize);
randomFile.close();
for (int i = 0; i < theadSize; i++)
{
int startPosition = i * block; // 从网络文件的什么位置开始
RandomAccessFile threadFile = new RandomAccessFile(file, "rw");
threadFile.seek(startPosition);// 从文件什么位置开始写入
}
private class DownloadThread extends Thread
{
private URL url;
private int startPosition;
private RandomAccessFile threadFile;
private int block;
private int threadId;
public DownloadThread(int threadId,URL url, int startPosition, RandomAccessFile threadFile, int block)
{
this.url = url;
this.startPosition = startPosition;
this.threadFile = threadFile;
this.block = block;
this.threadId = threadId ;
}
@Override
public void run()
{
try
{
HttpURLConnection conn;
conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setRequestProperty("Range", "bytes=" + startPosition + "-");
conn.setReadTimeout(6 * 1000);
conn.connect();
System.out.println(conn.getResponseCode());
InputStream inStream = conn.getInputStream();
byte[] data = new byte[1024];
int len = -1;
int readfilleSize = 0;
while (readfilleSize<block &&(len = inStream.read(data)) != -1)
{
threadFile.write(data, 0, len);
readfilleSize += len;//累计下载文件的大小
}
threadFile.close();
conn.disconnect();
System.out.println((this.threadId+1)+"线程下载完毕!");
} catch (IOException e)
{
e.printStackTrace();
}
}
}
public static void main(String args[]){
new DownloadThread(i,url, startPosition, threadFile, block).start();
}
byte[ ] quit = new byte[1];
System.in.read(quit);
while (!('q'==quit[0]))
{
Thread.sleep(3*1000);
}
}
}