android 文件上传、下载

android 文件上传、下载

主题脉络:

  • **HttpClient与HttpUrlConnection的比较
  • **HttpUrlConnection文件、请求数据上传
  • **HttpUrlConnection文件下载

一.文件上传之HttpClient与HttpUrlConnection的比较:
1.Httpclient的优点:代码编写方便,apache提供封装好的api可以直接使用,不用关注xml中的格式
2.HttpClient的缺点:不同的jar包差异很大,包的依赖关系有点乱,存在中文乱码(试了几个版本的jar包,网上的解决方案都不行)
3.HttpUrlConnection的优点:java语言提供的http请求的访问类,使用起来简单粗暴,更容易了解http请求的参数组装格式,遇到问题容易定位,跟服务端可以实现很好结合
4.HttpUrlConnection的缺点:格式比较复杂,稍不注意可能会写错
二.HttpUrlConnection文件、请求数据上传
提供两种解决方案,经验证都可用:

/**
     * 直接通过HTTP协议提交数据到服务器,实现表单提交功能
     * 
     * @param actionUrl
     *            上传路径
     * @param params
     *            请求参数 key为参数名,value为参数值
     * @param file
     *            上传文件
     */
    public static String post(String actionUrl, Map<String, String> params,
            FormFile[] files) {
        try {
            String BOUNDARY = "---------"
                    + java.util.UUID.randomUUID().toString(); // 数据分隔线
            String MULTIPART_FORM_DATA = "multipart/form-data";

            URL url = new URL(actionUrl);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setDoInput(true);// 允许输入
            conn.setDoOutput(true);// 允许输出
            conn.setUseCaches(false);// 不使用Cache
            conn.setRequestMethod("POST");
            conn.setRequestProperty("Connection", "Keep-Alive");
            conn.setRequestProperty("Charset", "UTF-8");
            conn.setRequestProperty("Content-Type", MULTIPART_FORM_DATA
                    + "; boundary=" + BOUNDARY);

            StringBuilder sb = new StringBuilder();

            // 上传的表单参数部分,格式请参考文章
            for (Map.Entry<String, String> entry : params.entrySet()) {// 构建表单字段内容
                sb.append("--");
                sb.append(BOUNDARY);
                sb.append("\r\n");
                sb.append("Content-Disposition: form-data; name=\""
                        + entry.getKey() + "\"\r\n\r\n");
                sb.append(entry.getValue());
                sb.append("\r\n");
            }
            DataOutputStream outStream = new DataOutputStream(
                    conn.getOutputStream());
            outStream.write(sb.toString().getBytes());// 发送表单字段数据

            // 上传的文件部分,格式请参考文章
            for (FormFile file : files) {
                StringBuilder split = new StringBuilder();
                split.append("--");
                split.append(BOUNDARY);
                split.append("\r\n");
                split.append("Content-Disposition: form-data;name=\""
                        + file.getFormname() + "\";filename=\""
                        + file.getFilname() + "\"\r\n");
                split.append("Content-Type: " + file.getContentType()
                        + "\r\n\r\n");
                outStream.write(split.toString().getBytes());
                outStream.write(file.getData(), 0, file.getData().length);
                outStream.write("\r\n".getBytes());
            }
            byte[] end_data = ("--" + BOUNDARY + "--\r\n").getBytes();// 数据结束标志
            outStream.write(end_data);
            outStream.flush();
            int cah = conn.getResponseCode();

            if (cah != 200)
                throw new RuntimeException("请求url失败");
            InputStream is = conn.getInputStream();
            int ch;
            StringBuilder b = new StringBuilder();
            while ((ch = is.read()) != -1) {
                b.append((char) ch);
            }
            outStream.close();
            conn.disconnect();
            return b.toString();
        } catch (Exception e) {
            LogUtil.e("http", e.getMessage(), e);
            return null;
        }
    }
    /**
     * 直接通过HTTP协议提交数据到服务器,实现表单提交功能(文件以流的方式来写,每次1k)
     * 
     * @param actionUrl
     *            上传路径
     * @param params
     *            请求参数 key为参数名,value为参数值
     * @param file
     *            上传文件
     */
    public static String post2(String actionUrl, Map<String, String> params,
            FormFile[] files) {
        try {
            String BOUNDARY = "---------"
                    + java.util.UUID.randomUUID().toString(); // 数据分隔线
            String MULTIPART_FORM_DATA = "multipart/form-data";

            URL url = new URL(actionUrl);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setDoInput(true);// 允许输入
            conn.setDoOutput(true);// 允许输出
            conn.setUseCaches(false);// 不使用Cache
            conn.setRequestMethod("POST");
            conn.setRequestProperty("Connection", "Keep-Alive");
            conn.setRequestProperty("Charset", "UTF-8");
            conn.setRequestProperty("Content-Type", MULTIPART_FORM_DATA
                    + "; boundary=" + BOUNDARY);

            StringBuilder sb = new StringBuilder();

            // 上传的表单参数部分,格式请参考文章
            for (Map.Entry<String, String> entry : params.entrySet()) {// 构建表单字段内容
                sb.append("--");
                sb.append(BOUNDARY);
                sb.append("\r\n");
                sb.append("Content-Disposition: form-data; name=\""
                        + entry.getKey() + "\"\r\n\r\n");
                sb.append(entry.getValue());
                sb.append("\r\n");
            }
            DataOutputStream outStream = new DataOutputStream(
                    conn.getOutputStream());
            outStream.write(sb.toString().getBytes());// 发送表单字段数据

            // 上传的文件部分,格式请参考文章
            for (FormFile file : files) {
                StringBuilder split = new StringBuilder();
                split.append("--");
                split.append(BOUNDARY);
                split.append("\r\n");
                split.append("Content-Disposition: form-data;name=\""
                        + file.getFormname() + "\";filename=\""
                        + file.getFilname() + "\"\r\n");
                split.append("Content-Type: " + file.getContentType()
                        + "\r\n\r\n");
                outStream.write(split.toString().getBytes());
                // outStream.write(file.getData(), 0, file.getData().length);
                if (file.getInStream() != null) {
                    byte[] buffer = new byte[1024];
                    int len = 0;
                    while ((len = file.getInStream().read(buffer, 0, 1024)) != -1) {
                        outStream.write(buffer, 0, len);
                    }
                    file.getInStream().close();
                }

                outStream.write("\r\n".getBytes());
            }
            byte[] end_data = ("--" + BOUNDARY + "--\r\n").getBytes();// 数据结束标志
            outStream.write(end_data);
            outStream.flush();
            int cah = conn.getResponseCode();

            if (cah != 200)
                throw new RuntimeException("请求url失败");
            InputStream is = conn.getInputStream();
            int ch;
            StringBuilder b = new StringBuilder();
            while ((ch = is.read()) != -1) {
                b.append((char) ch);
            }
            outStream.close();
            conn.disconnect();
            return b.toString();
        } catch (Exception e) {
            LogUtil.e("http", e.getMessage(), e);
            return null;
        }
    }

三.HttpUrlConnection实现文件下载:

/**
     * 
     * @param urlStr
     * @param sdcardPath
     * @param fileName
     * @return -1:文件下载出错 0:文件下载成功 1:文件已经存在
     */
    public File downFile(String urlStr, String sdcardPath, String fileName, Action.One<Long> processUpdateAction) {
        InputStream inputStream = null;
        File resultFile = null;
        try {
            FileUtil fileUtils = new FileUtil();
            // 对中文文件名进行utf-8转码
            int lastIndex = urlStr.lastIndexOf("/");
            urlStr = urlStr.substring(0, lastIndex + 1);
            URL url = new URL(urlStr + URLEncoder.encode(fileName, "utf-8"));

            HttpURLConnection urlConn = (HttpURLConnection) url.openConnection();
            urlConn.setRequestMethod("GET");
            urlConn.setReadTimeout(50* 1000); // 缓存的最长时间
            // urlConn.setDoOutput(true);// 2015-12-08 modify by zhanggang
            // 4.0中设置httpCon.setDoOutput(true),将导致请求以post方式提交
            // urlConn.setRequestProperty("Cookie", "ASP.NET_SessionId=" + ShareData.sessionID);
            // urlConn.setRequestProperty("Accept-Encoding", "identity");
            urlConn.setRequestProperty("Charset", "UTF-8");
            urlConn.connect();
            inputStream = urlConn.getInputStream();
            int contentLength = urlConn.getContentLength();

            if (inputStream != null) {
                // fileUtils.setTotalLength(contentLength);
                System.out.println("*********************" + urlStr);
                resultFile = fileUtils.write2SDFromInput(sdcardPath, fileName, inputStream, contentLength,
                        processUpdateAction);
            }
            if (resultFile != null) {
                return resultFile;
            }
        } catch (Exception e) {
            e.printStackTrace();
            return resultFile;
        } finally {
            try {
                if (inputStream != null) {
                    inputStream.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return resultFile;
    }
    public File write2SDFromInput(String sdcardPath, String fileName,
            InputStream input, int size, Action.One<Long> processUpdateAction) {
        File file = null;
        File filedir = null;
        OutputStream output = null;
        try {
            file = new File(sdcardPath.trim());
            filedir = file.getParentFile();
            if (!filedir.exists()) {
                filedir.mkdirs(); // 正确
            }
            if (!file.exists()) {
                file.createNewFile();
            }
            output = new FileOutputStream(file);

            byte[] buffer = new byte[size];
            int read = 0;
            long readTotal = 0;
            while ((read = input.read(buffer)) != -1) {
                // vt.progress=(int)((step*100)/totalLength);
                output.write(buffer, 0, read);
                readTotal += read;

                processUpdateAction.invoke((readTotal * 100) / size);
            }
            output.flush();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (output != null)
                    output.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return file;
    }

    public abstract class One<T> {
        /**
         * 执行方法。
         * 
         * @param arg
         *            :此委托封装的方法的参数。
         */
        public abstract void invoke(T arg);
    }

额,第一次写,欢迎拍砖。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值