Android Http实现文件的上传和下载
程序员文章站
2024-03-05 20:24:37
最近做一个项目,其中涉及到文件的上传和下载功能,大家都知道,这个功能实现其实已经烂大街了,遂、直接从网上荡了一堆代码用,结果,发现网上的代码真是良莠不齐,不是写的不全面,就...
最近做一个项目,其中涉及到文件的上传和下载功能,大家都知道,这个功能实现其实已经烂大街了,遂、直接从网上荡了一堆代码用,结果,发现网上的代码真是良莠不齐,不是写的不全面,就是有问题,于是自己重新整理了一番,把它们发出来,希望更多人能受用。
文件上传
通过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); }
源码地址:https://github.com/zuiwuyuan/http_uploader_downloader
以上便是我整理的android http实现文件的上传和下载方法,希望对更多的人有所帮助。