在下载前先自己建一个服务器方便测试
package com.example.day1_http_test.model;
import android.os.Handler;
//创建一个接口类
public interface FileNetInterface {
//参数一 要从服务器下载的文件 参数二 下载路径 参数三 在下载时传递下载进度
public void download(String url, String path, Handler handler);//下载
//参数一 服务器地址 参数二 要上传的文件 参数三 在下载时传递下载进度
public void duandian(String url, String path, Handler handler);//上传
//参数一 服务器地址 参数二 要上传的文件 参数三 在下载时传递下载进度 参数三 文件名
public void upload(String url,String path,Handler handler,String serverName);//断点续传
}
//写一个类实现接口
public class FileNetModel implements FileNetInterface{
public static final int DOWNLOAD_MAX = 101;//下载最大值
public static final int DOWNLOAD_PROGRESS = 102;//下载进度
public static final int UPLOAD_MAX = 201;//上传最大值
public static final int UPLOAD_PROGRESS = 201;//上传进度
public static final int DUANDIAN_MAX = 301;//上传最大值
public static final int DUANDIAN_PROGRESS = 302;//上传进度
//写三个线程
@Override
public void download(String url, String path, Handler handler) {
new DownloadThread(url,path,handler).start();
}
@Override
public void duandian(String url, String path, Handler handler) {
new DuanDianThread(url,path,handler).start();
}
@Override
public void upload(String url, String path, Handler handler, String serverName) {
new UploadThread(url,path,handler,serverName).start();
}
}
在主类中写三个按钮分别代表三个线程下载
private void initView() {
bt_download = findViewById(R.id.download);
bt_upload = findViewById(R.id.upload);
bt_duandian = findViewById(R.id.duandian);
bar1 = findViewById(R.id.bar1);
bar2 = findViewById(R.id.bar2);
bar3 = findViewById(R.id.bar3);
bt_download.setOnClickListener(this);
bt_upload.setOnClickListener(this);
bt_duandian.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.download:
model.download("http://169.254.37.29/e/c.png","/sdcard/Download/c.png",handler);
break;
case R.id.upload:
model.upload("http://169.254.37.29/e/","/sdcard/Download/他不懂.mp3",handler,"aa.mp3");
break;
case R.id.duandian:
model.duandian("http://uvideo.spriteapp.cn/video/2019/0512/56488d0a-7465-11e9-b91b-1866daeb0df1_wpd.mp4","/sdcard/Download/duandian.mp4",handler);
break;
}
}
现在开始写线程内容
//下载
public class DownloadThread extends Thread {
private String url;//下载地址
private String path;//要存放的地址
private Handler handler;//传递数据
public DownloadThread(String url, String path, Handler handler) {
this.url = url;
this.path = path;
this.handler = handler;
}
@Override
public void run() {
InputStream is = null;
FileOutputStream fos = null;
super.run();
try {
URL url1 = new URL(this.url);
HttpURLConnection urlConnection = (HttpURLConnection) url1.openConnection();
if(urlConnection.getResponseCode() == 200){
int max = urlConnection.getContentLength();//获取下载文件的长度
Message obtain1 = Message.obtain();
obtain1.what = FileNetModel.DOWNLOAD_MAX;
obtain1.obj = max;//返回给主类的进度条
handler.sendMessage(obtain1);
is = urlConnection.getInputStream();
fos = new FileOutputStream(path);
byte[] bytes = new byte[1024];
int len = 0;
int count = 0;//下载进度
while((len = is.read(bytes))!=-1){
count+=len;//进度增加
fos.write(bytes,0,len);
Message obtain = Message.obtain();
int progress = FileNetModel.DOWNLOAD_PROGRESS;
obtain.what = progress;
obtain.obj = count;
handler.sendMessage(obtain);
}
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
if(fos!=null){
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(is!=null){
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
//重点
上传文件:post请求
1.设置请求头信息:
Content-Length:请求体的长度
Content-Type:multipart/form-data; boundary=7e324741816d4
2.请求体:2部分
第一部分:要有换行
-----------------------------7e324741816d4
Content-Disposition: form-data; name=“file”; filename=“上传到服务器的名字”
Content-Type: media/mp4或者media/mp3或者image/mp3或者image/png
记住空行
第二部分:需要上传的文件:边读边写
//上传
/**
* http上传分4部分
* 1.首行
* 2.请求头
* 3.空行
* 4.请求体
*/
public class UploadThread extends Thread{
private String url;//发送的服务器地址
private String path;//要上传的文件地址
private Handler handler;//返回进度
private String serverName;//上传的文件名
public UploadThread(String url, String path, Handler handler, String serverName) {
this.url = url;
this.path = path;
this.handler = handler;
this.serverName = serverName;
}
@Override
public void run() {
super.run();
//先传一个最大进度回去
Message obtain = Message.obtain();
obtain.what = FileNetModel.UPLOAD_MAX;
obtain.arg1 = (int)new File(path).length();
handler.sendMessage(obtain);
OutputStream outputStream = null;
FileInputStream fis = null;
try {
URL url1 = new URL(this.url);
HttpURLConnection urlConnection = (HttpURLConnection) url1.openConnection();
//请求体
StringBuffer sb = new StringBuffer();
sb.append("-----------------------------7e324741816d4"+"\r\n");//可以直接复制
String encode = URLEncoder.encode(serverName);
sb.append("Content-Disposition: form-data; name=\"file\"; filename=\""+encode+"\""+"\r\n");
sb.append("Content-Type: media/mp3"+"\r\n");
sb.append("\r\n");
byte[] bytes = sb.toString().getBytes("UTF-8");
//请求头
urlConnection.setRequestProperty("Content-Length",bytes.length+new File(path).length()+"");
urlConnection.setRequestProperty("Content-Type","multipart/form-data; boundary=7e324741816d4");
//将模式设置为POST上传
urlConnection.setRequestMethod("POST");
//允许发送文件
urlConnection.setDoOutput(true);
outputStream = urlConnection.getOutputStream();
fis = new FileInputStream(path);
outputStream.write(bytes);
byte[] bytes1 = new byte[1024];
int len = 0;
int count = 0;
//这里注意不要直接判断是否连接成功 先发送
while((len = fis.read(bytes1))!=-1){
count+=len;//进度增加
Message obtain1 = Message.obtain();
obtain1.what = FileNetModel.UPLOAD_PROGRESS;
obtain.obj = count;
handler.sendMessage(obtain1);
outputStream.write(bytes1,0,len);
}
//这里判断连接成功 就代表以及上传成功
if(urlConnection.getResponseCode() == 200){
System.out.println("上传成功");
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
if(outputStream!=null){
try {
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(fis!=null){
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
断点续传
public class DuanDianThread extends Thread{
private String url;
private String paht;
private Handler handler;
int max;
int start;
int end;
public DuanDianThread(String url, String paht, Handler handler) {
this.url = url;
this.paht = paht;
this.handler = handler;
}
@Override
public void run() {
super.run();
try {
//获取文件大小 设置进度条最大值
URL url1 = new URL(this.url);
HttpURLConnection urlConnection = (HttpURLConnection) url1.openConnection();
max = urlConnection.getContentLength();
Message obtain1 = Message.obtain();
obtain1.what = FileNetModel.DUANDIAN_MAX;
obtain1.obj = max;
handler.sendMessage(obtain1);
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
File file = new File(paht);//要上传的文件
if(file.exists()){//判断是不是文件
start = (int) file.length();//将
}
end = max;
try {
URL url1 = new URL(url);
HttpURLConnection urlConnection = (HttpURLConnection) url1.openConnection();
urlConnection.setRequestProperty("Range","bytes="+start+"-"+end+"");
if(urlConnection.getResponseCode() == 206){//注意这里不是200 是206
InputStream is = urlConnection.getInputStream();
//new一个随机访问流对象 参数一:上传的文件 参数
//这个随机访问流就是用来继续你之前的下载进度上下载的流
RandomAccessFile randomAccessFile = new RandomAccessFile(paht, "rw");
//把上一次下载的长度设置上去
randomAccessFile.seek(start);
//继续下载
byte[] bytes = new byte[1024];
int len = 0;
int count = start;//用来获取你下载的长度 不断
while ((len = is.read(bytes))!=-1){
count+=len;//长度不断增加 知道下载结束
randomAccessFile.write(bytes,0,len);
Message obtain = Message.obtain();
obtain.what = FileNetModel.DUANDIAN_PROGRESS;
obtain.obj = count;
handler.sendMessage(obtain);
}
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}