• 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研发村 )

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

  • 相关阅读:
    谷歌浏览器禁止缩放和全面屏显示
    常用正则表达式
    封装时间函数
    年月日,时分秒,星期
    昨天,明天,月初,月末,最近七天,最近一个月,今天零时js
    React框架
    javaweb基础备忘
    一些java基础知识的备忘
    查看deepin版本
    java中堆栈的一些理解备忘
  • 原文地址:https://www.cnblogs.com/hehe520/p/6329933.html
Copyright © 2020-2023  润新知