最近做一个项目,其中涉及到文件的上传和下载功能,大家都知道,这个功能实现其实已经烂大街了,遂、直接从网上荡了一堆代码用,结果,发现网上的代码真是良莠不齐,不是写的不全面,就是有问题,于是自己重新整理了一番,把它们发出来,希望更多人能受用。

文件上传

通过org.apache.commons.httpclient.HttpClient来实现文件上传,该jar包可以直接从网上所搜、下载。

  1. /**
  2. * @param mContext 上下文
  3. * @param targetUrl 文件上传地址
  4. * @param filePath 文件路径
  5. */
  6. public void uploadFile(final Activity mContext, String targetUrl, final String filePath) {
  7. System.out.println("targetUrl: " + targetUrl + " filePath: " + filePath);
  8. if (TextUtils.isEmpty(filePath)) {
  9. Toast.makeText(mContext, "文件不存在", Toast.LENGTH_SHORT).show();
  10. return;
  11. }
  12. final PostMethod filePost = new PostMethod(targetUrl) {//这个用来中文乱码
  13. public String getRequestCharSet() {
  14. return "UTF-8";
  15. }
  16. };
  17. try {
  18. final HttpClient client = new HttpClient();
  19. File file = new File(filePath);
  20. if (file.exists() && file.isFile()) {
  21. long fileSize = file.length();
  22. if (fileSize >= 5 * 1024 * 1024) {
  23. Toast.makeText(mContext, "文件不得大于5M", Toast.LENGTH_SHORT).show();
  24. return;
  25. }
  26. } else {
  27. Toast.makeText(mContext, "文件不存在", Toast.LENGTH_SHORT).show();
  28. return;
  29. }
  30. // 上传文件和参数
  31. Part[] parts = new Part[]{new CustomFilePart(file.getName(), file),
  32. new StringPart("filename", file.getName(), "UTF-8")};
  33. filePost.setRequestEntity(new MultipartRequestEntity(parts, filePost.getParams()));
  34. new Thread(new Runnable() {
  35. @Override
  36. public void run() {
  37. int statuscode = 0;
  38. try {
  39. statuscode = client.executeMethod(filePost);
  40. } catch (IOException e) {
  41. e.printStackTrace();
  42. }
  43. final int finalStatuscode = statuscode;
  44. mContext.runOnUiThread(new Runnable() {
  45. @Override
  46. public void run() {
  47. if (finalStatuscode == HttpStatus.SC_OK) {
  48. Toast.makeText(mContext, "上传成功", Toast.LENGTH_SHORT).show();
  49. } else {
  50. Toast.makeText(mContext, "上传失败", Toast.LENGTH_SHORT).show();
  51. }
  52. }
  53. });
  54. }
  55. }).start();
  56. } catch (Exception ex) {
  57. ex.printStackTrace();
  58. }
  59. }

HttpClient的使用,常常会遇到乱码问题,我们主要在两个地方解决乱码问题:

  • 复写PostMethod 的getRequestCharSet,指定请求编码
  1. final PostMethod filePost = new PostMethod(targetUrl) {//这个用来中文乱码
  2. public String getRequestCharSet() {
  3. return "UTF-8";
  4. }
  5. };
  • 自定义FilePart,指定请求参数编码
  1. /**
  2. * 解决中文文件名乱码
  3. */
  4. public class CustomFilePart extends FilePart {
  5. public CustomFilePart(String filename, File file)
  6. throws FileNotFoundException {
  7. super(filename, file);
  8. }
  9. protected void sendDispositionHeader(OutputStream out) throws IOException {
  10. super.sendDispositionHeader(out);
  11. String filename = getSource().getFileName();
  12. if (filename != null) {
  13. out.write(EncodingUtil.getAsciiBytes(FILE_NAME));
  14. out.write(QUOTE_BYTES);
  15. out.write(EncodingUtil.getBytes(filename, "UTF-8"));
  16. out.write(QUOTE_BYTES);
  17. }
  18. }
  19. }

使用CustomFilePart添加参数:

  1. Part[] parts = new Part[]{new CustomFilePart(file.getName(), file),
  2. new StringPart("filename", file.getName(), "UTF-8")};
  3. filePost.setRequestEntity(new MultipartRequestEntity(parts, filePost.getParams()));

文件下载

通过HttpURLConnection下载文件。

  1. /**
  2. * @param urlStr 文件地址
  3. * @param path 文件保存路径
  4. * @param fileName 文件名
  5. * @return 文件的绝对路径
  6. */
  7. public String downFile(String urlStr, String path, String fileName) {
  8. InputStream inputStream = null;
  9. String filePath = null;
  10. try {
  11. FileUtils fileUtils = new FileUtils();
  12. //判断文件是否存在
  13. if (fileUtils.isFileExist(path + fileName)) {
  14. System.out.println("exits");
  15. filePath = SDPATH + path + fileName;
  16. } else {
  17. //得到io流
  18. inputStream = getInputStreamFromURL(urlStr);
  19. //从input流中将文件写入SD卡中
  20. File resultFile = fileUtils.write2SDFromInput(path, fileName, inputStream);
  21. if (resultFile != null) {
  22. filePath = resultFile.getPath();
  23. }
  24. }
  25. } catch (Exception e) {
  26. e.printStackTrace();
  27. } finally {
  28. try {
  29. if (inputStream != null)
  30. inputStream.close();
  31. } catch (IOException e) {
  32. e.printStackTrace();
  33. }
  34. }
  35. return filePath;
  36. }
  37. /**
  38. * 根据URL得到输入流
  39. *
  40. * @param urlStr
  41. * @return
  42. */
  43. public InputStream getInputStreamFromURL(String urlStr) {
  44. HttpURLConnection urlConn;
  45. InputStream inputStream = null;
  46. try {
  47. url = new URL(urlStr);
  48. urlConn = (HttpURLConnection) url.openConnection();
  49. inputStream = urlConn.getInputStream();
  50. } catch (Exception e) {
  51. e.printStackTrace();
  52. }
  53. return inputStream;
  54. }

文件下载其实很简单,说白了,就是通过HTTP获取InputStream ,然后通过解析InputStream 并写入到文件即可。

读取Inputstream并写入到SDCard。

  1. /**
  2. * 将一个InputStream里面的数据写入到SD卡中
  3. *
  4. * @param path 文件保存路径
  5. * @param fileName 文件保存的名字
  6. * @param input 文件输入流
  7. * @return 文件
  8. */
  9. public File write2SDFromInput(String path, String fileName,
  10. InputStream input) {
  11. File file = null;
  12. OutputStream output = null;
  13. try {
  14. // 创建文件夹
  15. createSDDir(path);
  16. // 创建文件
  17. file = createSDFile(path + fileName);
  18. // 开启输出流,准备写入文件
  19. output = new FileOutputStream(file);
  20. // 缓冲区
  21. byte[] buffer = new byte[FILESIZE];
  22. int count;
  23. while ((count = input.read(buffer)) != -1) {
  24. // 这里,请一定按该方式写入文件,不然时而会出现文件写入错误,数据丢失问题
  25. output.write(buffer, 0, count);
  26. }
  27. output.flush();
  28. } catch (Exception e) {
  29. e.printStackTrace();
  30. } finally {
  31. try {
  32. output.close();
  33. input.close();
  34. } catch (IOException e) {
  35. e.printStackTrace();
  36. }
  37. }
  38. return file;
  39. }

Inputstream写入到sdcard卡中,有个很重要的地方,先看下OutputStream 的write方法:



我推荐使用第二个方法write(byte[] b, int off, int len) ,目的是为了避免数据丢失。所以写文件代码如下:

  1. while ((count = input.read(buffer)) != -1) {
  2. // 这里,请一定按该方式写入文件,不然时而会出现文件写入错误,数据丢失问题
  3. output.write(buffer, 0, count);
  4. }

以上便是我整理的Android Http实现文件的上传和下载方法,希望对更多的人有所帮助。

如有疑问或建议,欢迎进QQ群来讨论交流:487786925( Android研发村 )

源码地址:https://github.com/zuiwuyuan/Http_Uploader_Downloader

Android Http实现文件的上传和下载的更多相关文章

  1. java实现ftp文件的上传与下载

    最近在做ftp文件的上传与下载,基于此,整理了一下资料.本来想采用java自带的方法,可是看了一下jdk1.6与1.7的实现方法有点区别,于是采用了Apache下的框架实现的... 1.首先引用3个包 ...

  2. 在SpringMVC框架下实现文件的 上传和 下载

    在eclipse中的javaEE环境下:导入必要的架包 web.xml的配置文件: <?xml version="1.0" encoding="UTF-8" ...

  3. SecureCRT使用sz和rz命令进行文件的上传和下载

    SecureCRT可以使用sz和rz命令进行文件的上传和下载. sz文件下载: 格式:sz 文件名称 即可将服务器的文件下载至本地. rz文件上传: 格式:rz 文件名称 即可将本地文件上传至服务器. ...

  4. 使用FTPClient进行文件服务器内文件的上传和下载

    我用的FTPClient是由Apache组织的commons-net.jar包中的API,这个包用起来非常的方便,很容易上手.我在项目开发的过程中主要用到了文件的上传和下载功能,下面将我开发的代码贴出 ...

  5. iOS开发中文件的上传和下载功能的基本实现-备用

    感谢大神分享 这篇文章主要介绍了iOS开发中文件的上传和下载功能的基本实现,并且下载方面讲到了大文件的多线程断点下载,需要的朋友可以参考下 文件的上传 说明:文件上传使用的时POST请求,通常把要上传 ...

  6. Apache FtpServer 实现文件的上传和下载

    1 下载需要的jar包 Ftp服务器实现文件的上传和下载,主要依赖jar包为: 2 搭建ftp服务器 参考Windows 上搭建Apache FtpServer,搭建ftp服务器 3 主要代码 在ec ...

  7. 初学Java Web(7)——文件的上传和下载

    文件上传 文件上传前的准备 在表单中必须有一个上传的控件 <input type="file" name="testImg"/> 因为 GET 方式 ...

  8. java web(四):request、response一些用法和文件的上传和下载

    上一篇讲了ServletContent.ServletCOnfig.HTTPSession.request.response几个对象的生命周期.作用范围和一些用法.今天通过一个小项目运用这些知识.简单 ...

  9. 黏包-黏包的成因、解决方式及struct模块初识、文件的上传和下载

    黏包: 同时执行多条命令之后,得到的结果很可能只有一部分,在执行其他命令的时候又接收到之前执行的另外一部分结果,这种显现就是黏包. 只有TCP协议中才会产生黏包,UDP协议中不会有黏包(udp协议中数 ...

随机推荐

  1. geoserver与OpenLayers配置

          geoserver与OpenLayers配置         目录   1     准备工作.... 4 1.1      需要用到的程序和资料... 4 2     地图格式转换方式(一 ...

  2. C#中int short Int16 Int32 Int64区别

    Java中没有Int32,Int64,,java中只有int,short,long Java中int就代表Int32 ,short就代表Int16,long就代表Int64 首先,几个基本的关键字: ...

  3. css3 实现明信片正背面翻转

    <!DOCTYPE html> <html lang="zh-cn" style="width: 100%;height: 100%;"> ...

  4. macOS 中Boost的安装和使用

    1 安装Boost 1.1 使用源码安装 下载Boost源码 解压放在任意目录,例如/home/wang/ ./bootstrap.sh,默认的位置是在usr/local下面;可以通过--prefix ...

  5. Binder对象死亡通知机制

    本文參考<Android系统源码情景分析>,作者罗升阳. 一.Binder库(libbinder)代码:        ~/Android/frameworks/base/libs/bin ...

  6. 2019-8-31-Developing-Universal-Windows-Apps-开发UWA应用-问答

    title author date CreateTime categories Developing Universal Windows Apps 开发UWA应用 问答 lindexi 2019-08 ...

  7. git命令移动文件夹到另一文件夹

  8. 导出excel表

    <?phppublic function export(){          #提现状态               $status = isset($_REQUEST['status'])? ...

  9. Statement对象

    Statement 对象 创建 Statement 对象 在你准备使用 Statement 对象执行 SQL 语句之前,你需要使用 Connection 对象的 createStatement() 方 ...

  10. 写GULP遇到的ES6问题详解

    Gulp.js 是一个自动化构建工具,开发者可以使用它在项目开发过程中自动执行常见任务.最近复习一下gulp一些基本的写法,在写了一些简单的uglify,rename,concat,clean的处理之 ...