Android上传文件

Android开发经常遇到要上传文件,我在网上找了一些文件上传的解决方案,自己做了一个整合。JavaWeb端参考:JavaWeb学习总结(五十)——文件上传和下载

直接上代码:

1,HttpURLConnection上传文件

package com.yyw.mutilthreaddownload;

import android.util.Log;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import java.util.UUID;

/**
 * HttpURLConnection上传文件
 */
public class HttpUpLoad {
    private static final String TAG = "uploadFile";
    private static final int TIME_OUT = 10 * 10000000; // 超时时间
    private static final String CHARSET = "utf-8"; // 设置编码
    public static final String SUCCESS = "1";
    public static final String FAILURE = "0";

    /**
     *
     * @param params 上传的参数
     * @param file 文件
     * @param RequestURL url地址
     * @return 返回
     */
    public static String uploadFile(HashMap<String,String>params,File file ,String RequestURL) {
        String BOUNDARY = UUID.randomUUID().toString(); // 边界标识 随机生成
        String PREFIX = "--", LINE_END = "\r\n";
        String CONTENT_TYPE = "multipart/form-data"; // 内容类型,指定为上传文件
        try {
            URL url = new URL(RequestURL);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setReadTimeout(TIME_OUT);
            conn.setConnectTimeout(TIME_OUT);
            conn.setDoInput(true); // 允许输入流
            conn.setDoOutput(true); // 允许输出流
            conn.setUseCaches(false); // 不允许使用缓存
            conn.setRequestMethod("POST"); // 请求方式,必须是大写POST,GET
            conn.setRequestProperty("Charset", CHARSET); // 设置编码
            conn.setRequestProperty("connection", "keep-alive");
            //在请求头中添加请求的分界符
            conn.setRequestProperty("Content-Type", CONTENT_TYPE + ";boundary="
                    + BOUNDARY);
            if (file != null) {
                /**
                 * 当文件不为空,把文件包装并且上传
                 */
                OutputStream outputSteam = conn.getOutputStream();
                //准备上传文件
                DataOutputStream dos = new DataOutputStream(outputSteam);

                StringBuffer sb = new StringBuffer();
                /************************上传表单的一些设置信息***********************************/
                if (params != null)
                    for (String key : params.keySet()) {
                        sb.append("--" + BOUNDARY + "\r\n");
                        sb.append("Content-Disposition: form-data; name=\"" + key
                                + "\"" + "\r\n");
                        sb.append("\r\n");
                        sb.append(params.get(key) + "\r\n");
                    }
                /************************上传文件的一些设置信息***********************************/
                sb.append(PREFIX);
                sb.append(BOUNDARY);
                sb.append(LINE_END);
                /**
                 * 这里重点注意: name里面的值为服务器端需要key 只有这个key 才可以得到对应的文件
                 * filename是文件的名字,包含后缀名的 比如:abc.png
                 */

                sb.append("Content-Disposition: form-data; name=\"file\"; filename=\""
                        + file.getName() + "\"" + LINE_END);
                sb.append("Content-Type: application/octet-stream; charset="
                        + CHARSET + LINE_END);
                sb.append(LINE_END);
                dos.write(sb.toString().getBytes());

                /************************上传文件***********************************/
                InputStream is = new FileInputStream(file);
                byte[] bytes = new byte[1024];
                int len = 0;
                while ((len = is.read(bytes)) != -1) {
                    dos.write(bytes, 0, len);
                    Log.i(TAG, "上传成功 +" + len);
                }
                is.close();
                /************************上传文件结束后的结束符号***********************************/
                dos.write(LINE_END.getBytes());
                byte[] end_data = (PREFIX + BOUNDARY + PREFIX + LINE_END)
                        .getBytes();
                dos.write(end_data);
                dos.flush();
                /**
                 * 获取响应码 200=成功 当响应成功,获取响应的流
                 */
                int res = conn.getResponseCode();
                if (res == 200) {
                    //获取返回内容
                    InputStream input = conn.getInputStream();
                    BufferedReader reader = new BufferedReader(new InputStreamReader(input));
                    String result = reader.readLine();
                    Log.i(TAG,"上传成功" + result);
                    reader.close();
                    is.close();
                    Log.i(TAG,"上传成功 +"+conn.getResponseMessage());
                    return SUCCESS;

                }
            }
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return FAILURE;
    }
}
HttpURLConnection上传文件有文件大小的限制。参考:从原理角度解析Android (Java) http 文件上传写了一个demo

package com.yyw.mutilthreaddownload;

import android.util.Log;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.Socket;
import java.net.URL;
import java.util.Map;

/**
 * Created by yyw on 2016/1/19.
 * 用Socket模拟HTTP上传比较大的文件,
 */
public class UpBigFile {
    public static final String TAG = "UpBigFile";
    private String charset = "UTF-8";

    /**
     *
     * @param params 参数
     * @param file 文件
     * @param url url
     */
    public void upLoadByScoket(Map<String, String> params,File file, String url) {
        try {
            String end = "\r\n";
            URL mUrl = new URL(url);
            String param = getParamString(params);//参数
            String fileHeader = getFileHeader(file);//文件的头
            String fileEnder = getFileEnder();//内容结束
            long l = param.length()+fileHeader.length()+fileEnder.length()+3*end.length()+file.length();//内容的长度
            String header = getHeaderString(url, mUrl,l);//请求头
            Socket mSocket = new Socket(mUrl.getHost(),mUrl.getPort());//用Socket模拟HTTP请求
            OutputStream os = mSocket.getOutputStream();
            PrintStream ps = new PrintStream(os,true,charset);
            Log.d(TAG, "upLoadByScoket: " + header);
            ps.print(header);
            ps.print(end);
            ps.print(param);
            ps.print(end);
            ps.print(fileHeader);
            ps.print(end);
            FileInputStream is = new FileInputStream(file);
            byte[] buffer = new byte[1024];
            int len = -1;
            int count = 0;
            while ((len = is.read(buffer))!=-1){
                count += len;
                Log.i(TAG,"上传成功 +"+count);
                os.write(buffer,0,len);
            }

            os.flush();
            ps.print(end);
            ps.print(fileEnder);
            InputStream input = mSocket.getInputStream();
            BufferedReader reader = new BufferedReader(new InputStreamReader(input));
            String result = reader.readLine();//返回内容
            Log.i(TAG, "上传成功" + result);
            reader.close();
            is.close();
            os.close();
            ps.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 文件开始符号
     * @param file
     * @return
     */
    private String getFileHeader(File file){
        String boundary = "******";
        String end = "\r\n";
        StringBuilder builder = new StringBuilder();
        builder.append("--");
        builder.append(boundary);
        builder.append(end);
        builder.append("Content-Disposition: form-data; name=\"file\";filename =\""+file.getName()+"\""+end);
        builder.append("Content-Type: application/octet-stream; Charset=");
        builder.append(charset);
        builder.append(end);
        return builder.toString();
    }

    /**
     * 内容结束符号
     * @return 内容结束符号
     */
    private String getFileEnder(){
        String boundary = "******";
        String end = "\r\n";
        return "--" + boundary + "--" + end;
    }

    /**
     * 获取请求的表单参数字符串
     * @param params 参数内容
     * @return 请求的表单参数字符串
     */
    private String getParamString(Map<String, String> params) {
        String boundary = "******";
        StringBuilder param = new StringBuilder();
        if (params != null)
            for (String key : params.keySet()) {
                param.append("--" + boundary + "\r\n");
                param.append("Content-Disposition: form-data; name=\"" + key
                        + "\"" + "\r\n");
                param.append("\r\n");
                param.append(params.get(key) + "\r\n");
            }
        return param.toString();
    }

    /**
     * 获取上传的请求头(模仿HTTP请求头)
     * @param url 地址
     * @param mUrl 地址URL
     * @param length 上传内容的长度
     * @return 上传请求头
     */
    private String getHeaderString(String url, URL mUrl,long length) {
        String end = "\r\n";
        String connection = "keep-alive";
        String contentType = "multipart/form-data";
        String boundary = "******";
//        POST http://192.168.0.55:8082/LearnNew/servlet/UploadHandleServlet HTTP/1.1
//        Charset: UTF-8
//        connection: keep-alive
//        Content-Type: multipart/form-data;boundary=******
//        User-Agent: Dalvik/1.6.0 (Linux; U; Android 4.1.1; GT-N8000 Build/JRO03C)
//        Host: 192.168.0.55:8082
//        Accept-Encoding: gzip
//        Content-Length: 2484
        StringBuilder header = new StringBuilder();
        header.append("POST ");
        header.append(url);
        header.append(" HTTP/1.1");
        header.append(end);
        header.append("Charset: ");
        header.append(charset);
        header.append(end);
        header.append("connection: ");
        header.append(connection);
        header.append(end);
        header.append("Content-Type: ");
        header.append(contentType);
        header.append(";boundary=");
        header.append(boundary);
        header.append(end);
        header.append("User-Agent: Dalvik/1.6.0 (Linux; U; Android 4.1.1; GT-N8000 Build/JRO03C)");
        header.append(end);
        header.append("Host: ");
        header.append(mUrl.getHost());
        header.append(end);
        header.append("Accept-Encoding: gzip");
        header.append(end);
        header.append("Content-Length: ");
        header.append(length);
        header.append(end);
        header.toString();
        return header.toString();
    }
}
上传的信息内容:

POST http://192.168.0.55:8082/LearnNew/servlet/UploadHandleServlet HTTP/1.1
Charset: UTF-8
connection: keep-alive
Content-Type: multipart/form-data;boundary=******
User-Agent: Dalvik/1.6.0 (Linux; U; Android 4.1.1; GT-N8000 Build/JRO03C)
Host: 192.168.0.55:8082
Accept-Encoding: gzip
Content-Length: 2484

--******
Content-Disposition: form-data; name="name"

zhangshan
--******
Content-Disposition: form-data; name="file";filename ="21_55-1447057315784.log"

replacements=[Ljava.lang.String;@40dcc5d0
HARDWARE=hws8301l
matchers=[Ljava.lang.String;@40dcc550
RADIO=unknown
HOST=screen105
HIDE_PRODUCT_INFO=false
TAGS=release-keys
PRODUCT_CHARM=MediaPad X1 7.0
ID=HuaweiMediaPad
MIN_VERSION_LENGTH=8
MANUFACTURER=HUAWEI
TYPE=user
TAG=Build
TIME=1403853553000
FINGERPRINT=Huawei/MediaPad/hws8301l:4.2.2/HuaweiMediaPad/S8301uV1R1C233B009:user/release-keys
UNKNOWN=unknown
PRODUCT_8VOGUE=MediaPad M1 8.0
BOARD=BalongV9R1
VERSION_MAX_SIZE=30
properties={ro.build.internal.t.version=S8-301uV100R001C233B009-01, ro.build.cust.id=S8-301uV100R001C233B009, ro.build.operator.id=S8-301uV100R001C233B009}
PRODUCT=MediaPad
FilePath=/cust/hwver.properties
DISPLAY=S8-301uV100R001C233B009
USER=jslave
DEVICE=hws8301l
MODEL=MediaPad M1 8.0
BOOTLOADER=unknown
CPU_ABI=armeabi-v7a
PRODUCT_UNKNOWN=unknown
CPU_ABI2=armeabi
IS_DEBUGGABLE=false
SERIAL=A8Z6R14613000263
BRAND=Huawei

--******--

Android的一个OkHttp的开源网络访问上传文件会很方便。

 /**
     * 上传文件
     * @param url
     * @param file
     */
    private void upFile(String url,File file){
        OkHttpClient client = new OkHttpClient();
        RequestBody body = new MultipartBody.Builder().setType(MultipartBody.FORM).addPart(Headers.of("Content-Disposition", "form-data; name=\"file\";filename =\""+file.getName()+"\""),RequestBody.create(null,file)).build();
        Request request = new Request.Builder().post(body).url(url).build();
        Call call = client.newCall(request);
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
            }
            @Override
            public void onResponse(Call call, Response response) throws IOException {
                String r = response.body().string();
                if (response.isSuccessful()) {
                    Log.i(TAG, "httpGet1 OK: " + r);
                } else {
                    Log.i(TAG, "httpGet1 error: " + r);
                }
            }
        });
    }





你可能感兴趣的:(android,文件下载)