Android Http实现文件的上传和下载
最近做一个项目,其中涉及到文件的上传和下载功能,大家都知道,这个功能实现其实已经烂大街了,遂、直接从网上荡了一堆代码用,结果,发现网上的代码真是良莠不齐,不是写的不全面,就是有问题,于是自己重新整理了一番,把它们发出来,希望更多人能受用。
文件上传
通过org.apache.commons.httpclient.HttpClient来实现文件上传,该jar包可以直接从网上所搜、下载。
/**
* @param mContext 上下文
* @param targetUrl 文件上传地址
* @param filePath 文件路径
*/
public void uploadFile(final Activity mContext, String targetUrl, final String filePath) {
System.out.println("targetUrl: " + targetUrl + " filePath: " + filePath);
if (TextUtils.isEmpty(filePath)) {
Toast.makeText(mContext, "文件不存在", Toast.LENGTH_SHORT).show();
return;
}
final PostMethod filePost = new PostMethod(targetUrl) {//这个用来中文乱码
public String getRequestCharSet() {
return "UTF-8";
}
};
try {
final HttpClient client = new HttpClient();
File file = new File(filePath);
if (file.exists() && file.isFile()) {
long fileSize = file.length();
if (fileSize >= 5 * 1024 * 1024) {
Toast.makeText(mContext, "文件不得大于5M", Toast.LENGTH_SHORT).show();
return;
}
} else {
Toast.makeText(mContext, "文件不存在", Toast.LENGTH_SHORT).show();
return;
}
// 上传文件和参数
Part[] parts = new Part[]{new CustomFilePart(file.getName(), file),
new StringPart("filename", file.getName(), "UTF-8")};
filePost.setRequestEntity(new MultipartRequestEntity(parts, filePost.getParams()));
new Thread(new Runnable() {
@Override
public void run() {
int statuscode = 0;
try {
statuscode = client.executeMethod(filePost);
} catch (IOException e) {
e.printStackTrace();
}
final int finalStatuscode = statuscode;
mContext.runOnUiThread(new Runnable() {
@Override
public void run() {
if (finalStatuscode == HttpStatus.SC_OK) {
Toast.makeText(mContext, "上传成功", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(mContext, "上传失败", Toast.LENGTH_SHORT).show();
}
}
});
}
}).start();
} catch (Exception ex) {
ex.printStackTrace();
}
}
HttpClient的使用,常常会遇到乱码问题,我们主要在两个地方解决乱码问题:
- 复写PostMethod 的getRequestCharSet,指定请求编码
final PostMethod filePost = new PostMethod(targetUrl) {//这个用来中文乱码
public String getRequestCharSet() {
return "UTF-8";
}
};
- 自定义FilePart,指定请求参数编码
/**
* 解决中文文件名乱码
*/
public class CustomFilePart extends FilePart {
public CustomFilePart(String filename, File file)
throws FileNotFoundException {
super(filename, file);
}
protected void sendDispositionHeader(OutputStream out) throws IOException {
super.sendDispositionHeader(out);
String filename = getSource().getFileName();
if (filename != null) {
out.write(EncodingUtil.getAsciiBytes(FILE_NAME));
out.write(QUOTE_BYTES);
out.write(EncodingUtil.getBytes(filename, "UTF-8"));
out.write(QUOTE_BYTES);
}
}
}
使用CustomFilePart添加参数:
Part[] parts = new Part[]{new CustomFilePart(file.getName(), file),
new StringPart("filename", file.getName(), "UTF-8")};
filePost.setRequestEntity(new MultipartRequestEntity(parts, filePost.getParams()));
文件下载
通过HttpURLConnection下载文件。
/**
* @param urlStr 文件地址
* @param path 文件保存路径
* @param fileName 文件名
* @return 文件的绝对路径
*/
public String downFile(String urlStr, String path, String fileName) {
InputStream inputStream = null;
String filePath = null;
try {
FileUtils fileUtils = new FileUtils();
//判断文件是否存在
if (fileUtils.isFileExist(path + fileName)) {
System.out.println("exits");
filePath = SDPATH + path + fileName;
} else {
//得到io流
inputStream = getInputStreamFromURL(urlStr);
//从input流中将文件写入SD卡中
File resultFile = fileUtils.write2SDFromInput(path, fileName, inputStream);
if (resultFile != null) {
filePath = resultFile.getPath();
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (inputStream != null)
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return filePath;
}
/**
* 根据URL得到输入流
*
* @param urlStr
* @return
*/
public InputStream getInputStreamFromURL(String urlStr) {
HttpURLConnection urlConn;
InputStream inputStream = null;
try {
url = new URL(urlStr);
urlConn = (HttpURLConnection) url.openConnection();
inputStream = urlConn.getInputStream();
} catch (Exception e) {
e.printStackTrace();
}
return inputStream;
}
文件下载其实很简单,说白了,就是通过HTTP获取InputStream ,然后通过解析InputStream 并写入到文件即可。
读取Inputstream并写入到SDCard。
/**
* 将一个InputStream里面的数据写入到SD卡中
*
* @param path 文件保存路径
* @param fileName 文件保存的名字
* @param input 文件输入流
* @return 文件
*/
public File write2SDFromInput(String path, String fileName,
InputStream input) {
File file = null;
OutputStream output = null;
try {
// 创建文件夹
createSDDir(path);
// 创建文件
file = createSDFile(path + fileName);
// 开启输出流,准备写入文件
output = new FileOutputStream(file);
// 缓冲区
byte[] buffer = new byte[FILESIZE];
int count;
while ((count = input.read(buffer)) != -1) {
// 这里,请一定按该方式写入文件,不然时而会出现文件写入错误,数据丢失问题
output.write(buffer, 0, count);
}
output.flush();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
output.close();
input.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return file;
}
Inputstream写入到sdcard卡中,有个很重要的地方,先看下OutputStream 的write方法:
我推荐使用第二个方法write(byte[] b, int off, int len) ,目的是为了避免数据丢失。所以写文件代码如下:
while ((count = input.read(buffer)) != -1) {
// 这里,请一定按该方式写入文件,不然时而会出现文件写入错误,数据丢失问题
output.write(buffer, 0, count);
}
以上便是我整理的Android Http实现文件的上传和下载方法,希望对更多的人有所帮助。
如有疑问或建议,欢迎进QQ群来讨论交流:487786925( Android研发村 )
Android Http实现文件的上传和下载的更多相关文章
- java实现ftp文件的上传与下载
最近在做ftp文件的上传与下载,基于此,整理了一下资料.本来想采用java自带的方法,可是看了一下jdk1.6与1.7的实现方法有点区别,于是采用了Apache下的框架实现的... 1.首先引用3个包 ...
- 在SpringMVC框架下实现文件的 上传和 下载
在eclipse中的javaEE环境下:导入必要的架包 web.xml的配置文件: <?xml version="1.0" encoding="UTF-8" ...
- SecureCRT使用sz和rz命令进行文件的上传和下载
SecureCRT可以使用sz和rz命令进行文件的上传和下载. sz文件下载: 格式:sz 文件名称 即可将服务器的文件下载至本地. rz文件上传: 格式:rz 文件名称 即可将本地文件上传至服务器. ...
- 使用FTPClient进行文件服务器内文件的上传和下载
我用的FTPClient是由Apache组织的commons-net.jar包中的API,这个包用起来非常的方便,很容易上手.我在项目开发的过程中主要用到了文件的上传和下载功能,下面将我开发的代码贴出 ...
- iOS开发中文件的上传和下载功能的基本实现-备用
感谢大神分享 这篇文章主要介绍了iOS开发中文件的上传和下载功能的基本实现,并且下载方面讲到了大文件的多线程断点下载,需要的朋友可以参考下 文件的上传 说明:文件上传使用的时POST请求,通常把要上传 ...
- Apache FtpServer 实现文件的上传和下载
1 下载需要的jar包 Ftp服务器实现文件的上传和下载,主要依赖jar包为: 2 搭建ftp服务器 参考Windows 上搭建Apache FtpServer,搭建ftp服务器 3 主要代码 在ec ...
- 初学Java Web(7)——文件的上传和下载
文件上传 文件上传前的准备 在表单中必须有一个上传的控件 <input type="file" name="testImg"/> 因为 GET 方式 ...
- java web(四):request、response一些用法和文件的上传和下载
上一篇讲了ServletContent.ServletCOnfig.HTTPSession.request.response几个对象的生命周期.作用范围和一些用法.今天通过一个小项目运用这些知识.简单 ...
- 黏包-黏包的成因、解决方式及struct模块初识、文件的上传和下载
黏包: 同时执行多条命令之后,得到的结果很可能只有一部分,在执行其他命令的时候又接收到之前执行的另外一部分结果,这种显现就是黏包. 只有TCP协议中才会产生黏包,UDP协议中不会有黏包(udp协议中数 ...
随机推荐
- Delphi 设计模式:《HeadFirst设计模式》Delphi7代码---状态模式[转]
{没有应用状态模式的代码} //工程文件 program Project1; {$APPTYPE CONSOLE} uses uGumballMachine in 'uGumballMachine. ...
- Linux下根目录root扩容
参考博客:https://blog.csdn.net/qq_36527339/article/details/81772996 1.首先虚拟机关机 —> 选中要扩容的虚拟机 —>编辑虚拟机 ...
- spring boot 的 ApplicationContext 及 getbean
在spring中,我们通过如下代码取得一个spring托管类: ApplicationContext ac = new FileSystemXmlApplicationContext("ap ...
- 类的加载classload和类对象的生成
在Java中最重要的可以说就是类的加载了.不论我们编写的功能多么复杂,或是多么简单,永远逃离不开的,就是将这个类从class文件加载到JVM中来. 类的加载过程 首先我们要了解一下类的加载过程,包括: ...
- 洛谷P2826 [USACO08NOV]光开关Light Switching [2017年6月计划 线段树02]
P2826 [USACO08NOV]光开关Light Switching 题目描述 Farmer John tries to keep the cows sharp by letting them p ...
- HR招聘_(二)_招聘方法论(招聘原因及原则)
1 招聘原因 离职 转岗 新增 工作量加大而无法负荷(若为短期工作量的加大可考虑外包或临时雇员) 业务发展需求(新产品线拓展,新事业部组建或组织架构变化等) 2 招聘原则 平等 面试官和候选人双方地位 ...
- (二)SpringBoot功能
web开发 spring boot web开发非常的简单,其中包括常用的json输出.filters.property.log等 json 接口开发 在以前的spring 开发的时候需要我们提供jso ...
- Linux下的MySQL主从同步
网上一些关于Linux下的MySQL主从同步教程非常之多,有些很简单的配置却弄的非常复杂,有些根本无法配通,下面是我通过简单的配置完成的主从同步过程,大家可以参考,此文章更适用于新手. 一.测试环境: ...
- Keil新建工程步骤
第一步:创建工程文件夹 1.新建一个文件夹,例如: 2.在文件夹下创建子文件夹: 文件夹说明: App:存放硬件控制程序: Libraries:存放固件库: Obj:存放生成的文件: Public:存 ...
- CMake学习笔记一
#设置cmake最低版本号 CMAKE_MINIMUM_REQUIRED(VERSION ) #设置工程名称 PROJECT(HelloWorld) #设置工程包含当前目录,非必须 SET(CMAKE ...