网络数据请求实践二:多文件上传的实现方法

上一篇blog中,展示了利用android-async-http来实现图片文件的上传和下载;本篇,将实现多文件的上传,基于标准的http来实现。

  1. 多文件上传MyUploader类的实现:
/**
 * 
 * 同步上传多个文件
 * 基于标准的http实现,需要在非UI线程中调用,以免阻塞UI。
 *
 */
public class MyUploader {
    private static final String TAG = "MyUploader";

    // 同步上传多个文件/
        /**
         * 同步上传File
         * 
         * @param Url
         * @param fullFileName
         *            : 全路径,ex. /sdcard/f/yh.jpg
         * @param fileName
         *            : file name, ex. yh.jpg
         * @return 服务器的响应结果(字符串形式)
         */
        public String MyUploadMultiFileSync(String Url,
                List<String> fileList, Map<String, String> params) {
            String reulstCode = "";
            String end = "\r\n";
            String twoHyphens = "--";
            String boundary = "--------boundary";

            try {
                URL url = new URL(actionUrl);
                HttpURLConnection con = (HttpURLConnection) url.openConnection();
                // 允许Input、Output,不使用Cache
                con.setDoInput(true);
                con.setDoOutput(true);
                con.setUseCaches(false);
                // 设置传送的method=POST
                con.setRequestMethod("POST");
                // setRequestProperty
                con.setRequestProperty("Connection", "Keep-Alive");
                con.setRequestProperty("Charset", "UTF-8");
                // con.setRequestProperty("Content-Type",
                // "application/x-www-form-urlencoded");
                con.setRequestProperty("Content-Type",
                        "multipart/form-data;boundary=" + boundary);

                StringBuffer s = new StringBuffer();
                // 设置DataOutputStream
                DataOutputStream dos = new DataOutputStream(con.getOutputStream());

                for (int i = 0; i < fileList.size(); i++) {

                    String filePath = fileList.get(i);

                    int endFileIndex = filePath.lastIndexOf("/");
                    String fileName = filePath.substring(endFileIndex + 1);
                    Log.i(TAG, "filename= " + fileName);
                    // set 头部
                    StringBuilder sb = new StringBuilder();

                    sb.append(twoHyphens);
                    sb.append(boundary);
                    sb.append(end);
                    sb.append("Content-Disposition: form-data; ");
                    sb.append("name=" + "\"" + "upload_file" +i + "\"");
                    sb.append(";filename=");
                    sb.append("\"" + fileName + "\"");
                    sb.append(end);

                    sb.append("Content-Type: ");
                    sb.append("image/jpeg");
                    sb.append(end);
                    sb.append(end);

                    // 1. write sb
                    dos.writeBytes(sb.toString());

                    // 取得文件的FileInputStream
                    FileInputStream fis = new FileInputStream(filePath);
                    // 设置每次写入1024bytes
                    int bufferSize = 1024;
                    byte[] buffer = new byte[bufferSize];

                    int length = -1;
                    // 从文件读取数据至缓冲区
                    while ((length = fis.read(buffer)) != -1) {
                        dos.write(buffer, 0, length);
                    }
                    dos.writeBytes(end);
                    fis.close();

                    dos.writeBytes(end);
                    dos.writeBytes(end);

                    //dos.writeBytes(end);
                    //dos.flush();
                    // close streams
                    //fis.close();
                }

                // set 尾部
                StringBuilder sb2 = new StringBuilder();

                if (params != null && !params.isEmpty()) {
                    for (String key : params.keySet()) {
                        String value = params.get(key);
                        sb2.append(twoHyphens);
                        sb2.append(boundary);
                        sb2.append(end);
                        sb2.append("Content-Disposition: form-data; ");
                        sb2.append("name=" + "\"");
                        sb2.append(key + "\"");
                        sb2.append(end);
                        sb2.append(end);
                        sb2.append(value);
                        sb2.append(end);
                    }
                }
                sb2.append(twoHyphens + boundary + end);
                dos.writeBytes(sb2.toString());
                dos.flush();
                Log.i(TAG, "sb2:" + sb2.toString());

                // 取得Response内容
                InputStream is = con.getInputStream();
                int ch;
                StringBuffer b = new StringBuffer();
                while ((ch = is.read()) != -1) {
                    b.append((char) ch);
                }
                reulstCode = b.toString().trim();
                // 关闭
                dos.close();
            } catch (IOException e) {
                Log.i(TAG, "IOException: " + e);
                e.printStackTrace();
            }

            return reulstCode;
        }
}

2. 调用方法:

由于MyUploader的MyUploadMultiFileSync本身是同步的函数请求,所以,这个函数需要在非UI线程中执行。本例采用Thread+Handler的方式来进行说明。
下面是activity的主要代码,功能是将cache目录中的的jpg文件上传到指定的服务器:

public void uploadThreadTest() {
        new Thread(new Runnable() {
            @Override
            public void run() {

                try {
                    upload();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

        }).start();

    }

    private void upload() {
        String url = "https://httpbin.org/post";
        List<String> fileList = getCacheFiles();

        if (fileList == null) {
            myHandler.sendEmptyMessage(-1);
        }else {
            MyUploader myUpload = new MyUploader();
            //同步请求,直接返回结果,根据结果来判断是否成功。
            String reulstCode = myUpload.MyUploadMultiFileSync(url, fileList, null);
            Log.i(TAG, "upload reulstCode: " + reulstCode);
            myHandler.sendEmptyMessage(0);

        }
    }

    private List<String> getCacheFiles() {
        List<String> fileList = new ArrayList<String>();
        File catchPath = mContext.getCacheDir();

        if (catchPath!=null && catchPath.isDirectory()) {

            File[] files = catchPath.listFiles();
            if (files == null || files.length<1) {
                return null;
            }
            for (int i = 0; i < files.length; i++) {
                if (files[i].isFile() && files[i].getAbsolutePath().endsWith(".jpg")) {
                    fileList.add(files[i].getAbsolutePath());
                }

            }
            return fileList;

        }
        return null;


    }
    handler/
    private Handler myHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            Log.i(TAG,"handleMessage msg===" + msg);
            if (msg.what == -1) {
                Toast.makeText(mContext, "not find file!", Toast.LENGTH_LONG).show();
                return;
            }else {
                Toast.makeText(mContext, "upload success!", Toast.LENGTH_LONG).show();
            }

        }

    };

3 项目demo代码地址:

https://github.com/ranke/HttpAsyncTest

开源的力量是无穷的!

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

liranke

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值