欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

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实现文件的上传和下载方法,希望对更多的人有所帮助。