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);}

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

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

当一个人把寂寞当作人生预约的美丽,

Android Http实现文件的上传和下载

相关文章:

你感兴趣的文章:

标签云: