目前使用最多的就是HTTP协议,用于上传文件,下载图片等等。
1、首先使用HTTP协议去下载一个图片
一般步骤:
1、首先建立URLHttpConnection,传递一个要下载的文件的路径url。
2、再去设置网络连接的方式(post、get),获取响应码,如果不是以2开头的,则说明连接失败。之后就开始下载文件。
3、这个是支持段点下载的。
public static void main(String[] args) {
try {
File file = new File("test.jpg");
String url = "http://tnfs.tngou.net/image/top/160818/580c92bbb8903774521052d708af41da.jpg";
HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
connection.setRequestMethod("GET");
// 获取头部信息
/* Map<String, List<String>> fields = connection.getHeaderFields();
for (Map.Entry<String, List<String>> entry : fields.entrySet()) {
System.out.println(entry.getKey());
System.out.println(entry.getValue());
System.out.println("===================");
}*/
long sum = 0;
// 看文件是否存在,如果存在重新设置文件下载的位置,为了可以端点下载。
if (file.exists()) {
sum = file.length();
// 重新设置下载的位置
connection.setRequestProperty("Range", "bytes=" + file.length() + "-");
}
int code = connection.getResponseCode();
// 获得连接的相应码,具体可百度各个响应码的含义
if (code == 200 || code == 206) {
int contentLength = connection.getContentLength();
System.out.println(contentLength);
contentLength += sum;
FileOutputStream fos = new FileOutputStream(file,true);
InputStream is = connection.getInputStream();
// 缓冲区
byte[] buffer = new byte[102400];
int length;
System.out.println(Thread.currentThread());
// 记录当前时间,为了之后计算下载速度
long startTime = System.currentTimeMillis();
while ((length = (is.read(buffer))) != -1) {
fos.write(buffer, 0, length);
sum += length;
// 定义百分比
float percent = sum * 100.0f / contentLength;
// 显示进度条
System.out.print("\r[");
int p = ((int) (percent / 2));
for (int i = 0; i < 50; i++) {
if (i < p) {
System.out.print('=');
} else if (i == p) {
System.out.print('>');
} else {
System.out.print(' ');
}
}
System.out.print(']');
System.out.printf("\t%.2f", percent);
// 单位
long speed = sum * 1000 / ((System.currentTimeMillis() - startTime));
if (speed > (1 << 20)) {
System.out.printf("\t%d M/s", speed >> 20);
} else if (speed > (1 << 10)) {
System.out.printf("\t%d KB/s", speed >> 10 );
} else {
System.out.printf("\t%d B/s", speed);
}
}
}
} catch (ProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
运行结果:
2、多线程下载文件
1、多线程下载文件中,具体做法和第一个例子相似,也是先建立URLHTTPConnection连接,之后将一个下载的文件的长度截成多段,分别用不同的线程去下载。
2、多线程下载文件中,如果要使用进度条,就要专门去记录文件的下载位置。一般我们在下载时,都会有两个文件,其中一个就是记录下载的位置的。
// 测试类
package com.xiaohong.tea;
import javax.swing.event.DocumentEvent;
import java.io.File;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
/*
* 多线程下载
*/
public class ThreadDownload {
public static void main(String[] args) {
try {
String url = "http://tnfs.tngou.net/image/top/160818/5371ba6d3aa5a7a3467f3de0a565328b.jpg/top/160818/8fc9cf6c54280c859fcb293060739b0d.png/top/160818/07ad460b705300eee4ce9e2c3bb69587.jpg";
File file = new File("haha.jpg");
HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
connection.setRequestMethod("GET");
int contentLength = connection.getContentLength();
// 分成5个线程下载
int range = contentLength / 5;
for (int i = 0; i < 5; i++) {
int start = i * range;
int end = start + range;
if (i == 4) {
// 最后一个线程要全部下载
end = contentLength - 1;
}
new Thread(new DownloadRunable(url, file, start, end)).start();
System.out.println("OK" + start);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
// 下载线程类
package com.xiaohong.tea;
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 DownloadRunable implements Runnable {
private String url;
private File file;
private int start;
private int end;
public DownloadRunable(String url, File file, int start, int end) {
this.url = url;
this.file = file;
this.start = start;
this.end = end;
}
@Override
public void run() {
try {
HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
connection.setRequestMethod("GET");
// 设置下载的范围
connection.setRequestProperty("Range", "bytes=" + start + "-" + end);
// 容易在文件中跳转,不要忘记设置读取方式
RandomAccessFile accessFile = new RandomAccessFile(file, "rw");
accessFile.seek(start);
int code = connection.getResponseCode();
if (code == 206) {
InputStream is = connection.getInputStream();
byte[] buffer = new byte[102400];
int length;
while ((length = is.read(buffer)) != -1) {
accessFile.write(buffer, 0, length);
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
3、还可以通过HTTP下一在网上下载json字符串,进而进行解析成想要的数据类型,详情请见下篇博客。对于XML解析,使用HTTP协议可以完成,但很麻烦,一般不使用。