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

来源:互联网 发布:捕鱼源码字母有哪些? 编辑:程序博客网 时间:2024/05/29 09:08

上一篇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 0
原创粉丝点击