Android中的文件上传下载
一、文件上传
1. 使用HttpUrlConnection
//此处省略线程操作和Handler通信
File file = new File(etUpload.getText().toString());
FileInputStream in = new FileInputStream(file);
URL url = new URL(path);
// 开启连接
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
// 设置请求方式
conn.setRequestMethod("POST");
//设置文件大小
conn.setChunkedStreamingMode(0);
// 设置超时
conn.setConnectTimeout(10000);
// 设置发送内容
conn.setDoInput(true);
byte[] buffer = new byte[1024];
int len = 0;
while ((len = in.read(buffer)) != -1) {
conn.getOutputStream().write(buffer, 0, len);
}
in.close();
2. 使用AsyncHttpClient
//创建client
AsyncHttpClient client = new AsyncHttpClient();
//准备请求
RequestParams params = new RequestParams();
params.put("file", new File(etUpload.getText().toString()));
//发出请求
client.post(path, params, new AsyncHttpResponseHandler(){
@Override
public void onSuccess(int statusCode, String content) {
//获取响应体
Toast.makeText(MainActivity02.this, "发送成功!", Toast.LENGTH_SHORT).show();
}
@Override
public void onFailure(Throwable error, String content) {
//获取响应体
Toast.makeText(MainActivity02.this, "发送失败!", Toast.LENGTH_SHORT).show();
}
});
二、文件下载
1. 多线程下载过程
- 获取连接
- 准备请求信息
- 获取服务端文件大小
- 客户端创建同等大小的随机访问文件
- 创建多线程,分配任务
- 分段请求资源并写入到随机访问文件中
- 通知下载完毕并断开连接
2. 多线程下载(HttpUrlConnection)
public void downloadImage(View v) {
new Thread() {
public void run() {
HttpURLConnection conn = null;
try {
// 获取连接
URL url = new URL(path);
conn = (HttpURLConnection) url.openConnection();
// 准备请求信息,请求方式,最大延时
conn.setRequestMethod("GET");
conn.setReadTimeout(10000);
// 获取响应信息
if (conn.getResponseCode() == 200) {
// 获取服务端文件大小
int length = conn.getContentLength();
// 客户端新建同等大小的文件
RandomAccessFile raf = new RandomAccessFile(fileName,
"rw");
raf.setLength(length);
raf.close();
// 创建多线程,分配任务
int threadCount = 3;// 线程数量
int blockSize = length / threadCount;// 每个线程负责的任务量
for (int i = 0; i < threadCount; i++) {
int start = i * blockSize;// 开始读取位置
int end = (i + 1) * blockSize - 1;// 结束读取位置
if (i == threadCount - 1) {
end = length;
}
// 多线程下载
new AsyncDownload(i, start, end).start();
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (conn != null){
conn.disconnect();// 断开连接
}
}
}
}.start();
}
private class AsyncDownload extends Thread {
int threadIndex;
int start;
int end;
AsyncDownload(int threadIndex, int start, int end) {
this.threadIndex = threadIndex;
this.start = start;
this.end = end;
}
@Override
public void run() {
HttpURLConnection conn=null;
try {
URL url = new URL(path);
// 获取连接
conn = (HttpURLConnection) url.openConnection();
// 准备请求
conn.setRequestMethod("GET");
conn.setRequestProperty("range", "bytes=" + start + "-" + end);
conn.setReadTimeout(10000);
// 获取响应,请求码表示请求一段信息完毕
if (conn.getResponseCode() == 206) {
// 获取对应的字节流并写入文件
InputStream is = conn.getInputStream();
RandomAccessFile raf = new RandomAccessFile(fileName, "rw");
raf.seek(start);
byte[] buff = new byte[1024];
int len = 0;
while ((len = is.read(buff)) != -1) {
raf.write(buff, 0, len);
}
// 关闭流
raf.close();
System.out.println("第" + threadIndex + "个线程下载完毕");
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (conn != null) {
// 关闭连接
conn.disconnect();
}
//使用唯一的对象加同步,保证runningThread数据的正确性
synchronized (MainActivity.class) {
runningThread--;
if (runningThread == 0) {
Message msg = new Message();
msg.what = DOWNLOAD_FINISH;
mHandler.sendMessage(msg);
}
}
}
}
}
3. 多线程下载(AsyncHttpClient)
使用BinaryHttpResponseHandler
public void downloadImage(View v) {
// 建立一个访问client
AsyncHttpClient client = new AsyncHttpClient();
// 发出请求
client.get(path, new BinaryHttpResponseHandler(){
@Override
public void onSuccess(byte[] binaryData) {
try {
//获取文件并保存
FileOutputStream out = new FileOutputStream(new File(fileName));
out.write(binaryData);
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
});
}