Ver Fonte

分片上传

zhaofuxin há 4 anos atrás
pai
commit
90a3889e25

+ 192 - 0
app/src/main/java/com/jld/vod/utils/FileUtils.java

@@ -0,0 +1,192 @@
+package com.jld.vod.utils;
+
+import java.io.*;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @program: mqttService
+ * @description: 文件分片发送
+ * @author: MoJiaJian
+ * @create: 2021-09-17 14:49
+ **/
+public class FileUtils {
+
+    /**
+     * 文件分块工具
+     *
+     * @param offset    起始偏移位置
+     * @param file      文件
+     * @param blockSize 分块大小
+     * @return 分块数据
+     */
+
+    public static byte[] getBlock(long offset, File file, int blockSize) {
+
+        byte[] result = new byte[blockSize];
+
+        RandomAccessFile accessFile = null;
+
+        try {
+
+            accessFile = new RandomAccessFile(file, "r");
+
+            accessFile.seek(offset);
+
+            int readSize = accessFile.read(result);
+
+            if (readSize == -1) {
+
+                return null;
+
+            } else if (readSize == blockSize) {
+
+                return result;
+
+            } else {
+
+                byte[] tmpByte = new byte[readSize];
+
+                System.arraycopy(result, 0, tmpByte, 0, readSize);
+
+                return tmpByte;
+
+            }
+
+        } catch (IOException e) {
+
+            e.printStackTrace();
+
+        } finally {
+
+            if (accessFile != null) {
+
+                try {
+
+                    accessFile.close();
+
+                } catch (IOException e1) {
+
+                }
+
+            }
+
+        }
+
+        return null;
+
+    }
+
+//
+//    public static String UploadFileByHttpClient(File file, String url, Map<String, Object> params) {
+//        StringBuilder result = new StringBuilder();
+//        CloseableHttpClient httpClient = HttpClients.createDefault();
+//        CloseableHttpResponse response = null;
+//        InputStream content = null;
+//        BufferedReader in = null;
+//        try {
+//            HttpPost httpPost = new HttpPost(url);
+//            //HttpMultipartMode.RFC6532参数的设定是为避免文件名为中文时乱码
+//            MultipartEntityBuilder builder = MultipartEntityBuilder.create().setMode(HttpMultipartMode.RFC6532);
+//            //httpPost.addHeader("header1", "111");//头部放文件上传的head可自定义
+//            builder.addBinaryBody("file", file, ContentType.MULTIPART_FORM_DATA, file.getName());
+//            params.forEach((k, v) -> builder.addTextBody(k, v.toString()));//解析参数
+//            HttpEntity entity = builder.build();
+//            httpPost.setEntity(entity);
+//            response = httpClient.execute(httpPost);// 执行提交
+//            HttpEntity responseEntity = response.getEntity();//接收调用外部接口返回的内容
+//            if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
+//                // 返回的内容都在content中
+//                content = responseEntity.getContent();
+//                // 定义BufferedReader输入流来读取URL的响应
+//                in = new BufferedReader(new InputStreamReader(content));
+//                String line;
+//                while ((line = in.readLine()) != null) {
+//                    result.append(line);
+//                }
+//                if (!result.toString().equals("")) {
+//                    System.out.println("上传文件" + file.getName() + "返回参数==>" + result);
+//                } else {
+//                    System.out.println("上传文件失败:返回result为null");
+//                }
+//            }
+//        } catch (Exception e) {
+//            System.out.println("上传文件失败:" + e);
+//        } finally {//处理结束后关闭httpclient的链接
+//            try {
+//                httpClient.close();
+//                if (content != null) {
+//                    content.close();
+//                }
+//                if (in != null) {
+//                    in.close();
+//                }
+//            } catch (IOException e) {
+//                e.printStackTrace();
+//            }
+//        }
+//        return result.toString();
+//    }
+
+//    public static void main(String[] args) throws IOException {
+//        String url = "http://127.0.0.1:8080/uploadFile";
+//
+//        File file = new File("E:\\DY\\asd.mp4");
+//        String s1 = file.getName();
+//        System.out.println(s1.split("\\.")[0]);
+//
+//        //计算文件总分片大小
+//        long length = file.length();//当前文件大小
+//        int total = 0;//总分片大小
+//
+//        int CHUNK_SIZE = 10*1024*1024; //分片大小 最好是long型
+//
+//        if (length % CHUNK_SIZE ==0){
+//            total = (int) (length / CHUNK_SIZE);
+//        }else {
+//            total = (int) (length / CHUNK_SIZE) + 1 ;
+//        }
+//
+//        boolean tmp = true; //读取进度结束符
+//        int index = 0;
+//        //一次1M进行读取
+//        while (tmp) {
+//            byte[] block = getBlock(CHUNK_SIZE * index, file, CHUNK_SIZE);
+//            if (block != null) {
+//                String filePath = "E:\\DY\\" + s1 + "_"+index+".tmp";//缓存目录 外部自定义
+//                OutputStream out = new FileOutputStream(filePath);
+//                InputStream is = new ByteArrayInputStream(block);
+//                byte[] buff = new byte[1024];
+//                int len = 0;
+//                while ((len = is.read(buff)) != -1) {
+//                    out.write(buff, 0, len);
+//                }
+//                is.close();
+//                out.close();
+//                /*
+//                 * 模拟发送请求
+//                 */
+//                //设置参数
+//                int finalTotal = total;
+//                int finalIndex = index;
+//                Map<String, Object> map = new HashMap<String, Object>() {{
+//                    put("chunks", finalTotal);
+//                    put("chunk", finalIndex);
+//                    put("chunkSize",CHUNK_SIZE);//固定块大小
+//                    put("md5","000");
+//                    put("resId","000");
+//                    put("mid","000");
+//                    put("fileName",s1);
+//                }};
+//                String s = UploadFileByHttpClient(new File(filePath), url, map);
+//                System.out.println(s);//输出返回内容
+//                index++;
+//                //todo 删除缓存文件
+//                new File(filePath).delete();
+//            } else {
+//                tmp = false;
+//            }
+//        }
+//        System.out.println("读取了文件:" + index + "次");
+//    }
+}

+ 146 - 0
app/src/main/java/com/jld/vod/utils/http/FileUploadUtils.java

@@ -0,0 +1,146 @@
+package com.jld.vod.utils.http;
+
+import android.content.Context;
+import android.util.Log;
+
+import com.jld.vod.utils.FileUtils;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+
+import okhttp3.MediaType;
+import okhttp3.MultipartBody;
+import okhttp3.OkHttpClient;
+import okhttp3.Request;
+import okhttp3.RequestBody;
+
+public class FileUploadUtils {
+
+    private static OkHttpClient okHttpClient = new OkHttpClient.Builder().connectTimeout(10000, TimeUnit.MILLISECONDS)
+            .readTimeout(10000,TimeUnit.MILLISECONDS)
+            .writeTimeout(10000, TimeUnit.MILLISECONDS).
+                    build();
+
+    public static void postFile(Context mContext ,String url, final ProgressListener listener, okhttp3.Callback callback, File videopath, Long mid, Long resId){
+
+        okHttpClient.dispatcher().setMaxRequests(1);
+        okHttpClient.dispatcher().setMaxRequestsPerHost(5);
+        MultipartBody.Builder builder = new MultipartBody.Builder();
+        builder.setType(MultipartBody.FORM);
+
+
+        //计算文件总分片大小
+        long length = videopath.length();//当前文件大小
+        int total = 0;//总分片大小
+        String s1 = videopath.getName();
+        int CHUNK_SIZE = 10*1024*1024; //分片大小 最好是long型
+
+        if (length % CHUNK_SIZE ==0){
+            total = (int) (length / CHUNK_SIZE);
+        }else {
+            total = (int) (length / CHUNK_SIZE) + 1 ;
+        }
+
+        boolean tmp = true; //读取进度结束符
+        int index = 0;
+        //一次1M进行读取
+        while (tmp) {
+            byte[] block = FileUtils.getBlock(CHUNK_SIZE * index, videopath, CHUNK_SIZE);
+            if (block != null) {
+             //   String filePath = "E:\\DY\\" + s1 + "_"+index+".tmp";//缓存目录 外部自定义
+
+                File filePath = new File( mContext.getFilesDir(), "video/"+ s1 + "_"+index+".tmp");
+
+                OutputStream out = null;
+                try {
+                    out = new FileOutputStream(filePath.getAbsolutePath());
+                    InputStream is = new ByteArrayInputStream(block);
+                    byte[] buff = new byte[1024];
+                    int len = 0;
+                    while ((len = is.read(buff)) != -1) {
+                        out.write(buff, 0, len);
+                    }
+                    is.close();
+                    out.close();
+                } catch (FileNotFoundException e) {
+                    e.printStackTrace();
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+
+                /*
+                 * 模拟发送请求
+                 */
+                //设置参数
+                int finalTotal = total;
+                int finalIndex = index;
+                Map<String, Object> map = new HashMap<String, Object>() {{
+                    put("chunks", finalTotal);
+                    put("chunk", finalIndex);
+                    put("chunkSize",CHUNK_SIZE);//固定块大小
+                    put("md5","000");
+                    put("resId","000");
+                    put("mid","000");
+                    put("fileName",s1);
+                }};
+                RequestBody body = setRequestBody(map);
+
+                //第一个参数要与Servlet中的一致
+//                builder.addFormDataPart("file",videopath.getName(), RequestBody.create(MediaType.parse("application/octet-stream"),videopath));
+//                if (mid != 123456)
+//                {
+//                    builder.addFormDataPart("mid",mid.toString());
+//                }
+//                builder.addFormDataPart("resId",resId.toString());
+
+//                MultipartBody multipartBody = builder.build();
+
+
+                Request request  = new Request.Builder().url(url).post(new ProgressRequestBody(body,listener)).build();
+                okHttpClient.newCall(request).enqueue(callback);
+
+//                String s = UploadFileByHttpClient(new File(filePath), url, map);
+//
+//
+//
+//                System.out.println(s);//输出返回内容
+                index++;
+                //todo 删除缓存文件
+                new File(filePath.getAbsolutePath()).delete();
+            } else {
+                tmp = false;
+            }
+        }
+        System.out.println("读取了文件:" + index + "次");
+    }
+    /**
+     * post的请求参数,构造RequestBody
+     *
+     * @param BodyParams
+     * @return
+     */
+    private static RequestBody setRequestBody(Map<String, Object> BodyParams) {
+        RequestBody body = null;
+        okhttp3.FormBody.Builder formEncodingBuilder = new okhttp3.FormBody.Builder();
+        if (BodyParams != null) {
+            Iterator<String> iterator = BodyParams.keySet().iterator();
+            String key = "";
+            while (iterator.hasNext()) {
+                key = iterator.next().toString();
+                formEncodingBuilder.add(key, (String) BodyParams.get(key));
+                Log.d("post http", "post_Params===" + key + "====" + BodyParams.get(key));
+            }
+        }
+        body = formEncodingBuilder.build();
+        return body;
+    }
+}

+ 100 - 0
app/src/main/java/com/jld/vod/utils/http/MDProgressRequestBody.java

@@ -0,0 +1,100 @@
+package com.jld.vod.utils.http;
+
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+
+import com.jld.vod.model.ProgressModel;
+
+import java.io.IOException;
+import okhttp3.MediaType;
+import okhttp3.RequestBody;
+import okio.Buffer;
+import okio.BufferedSink;
+import okio.ForwardingSink;
+import okio.Okio;
+import okio.Sink;
+
+/**
+ * Created by zhaofuxin on 2019/9/11.
+ */
+
+public class MDProgressRequestBody extends RequestBody {
+    public static final int UPDATE = 0x01;
+    private RequestBody requestBody;
+    private ProgressListener mListener;
+    private BufferedSink bufferedSink;
+    private MyHandler myHandler;
+    public MDProgressRequestBody(RequestBody body, ProgressListener listener) {
+        requestBody = body;
+        mListener = listener;
+        if (myHandler==null){
+            myHandler = new MyHandler();
+        }
+    }
+
+    class MyHandler extends Handler {
+
+        public MyHandler() {
+            super(Looper.getMainLooper());
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what){
+                case UPDATE:
+                    ProgressModel progressModel = (ProgressModel) msg.obj;
+                    if (mListener!=null)mListener.onProgress(progressModel.getCurrentBytes(),progressModel.getContentLength(),progressModel.isDone());
+                    break;
+
+            }
+        }
+
+
+    }
+
+    @Override
+    public MediaType contentType() {
+        return requestBody.contentType();
+    }
+
+    @Override
+    public long contentLength() throws IOException {
+        return requestBody.contentLength();
+    }
+
+    @Override
+    public void writeTo(BufferedSink sink) throws IOException {
+
+        if (bufferedSink==null){
+            bufferedSink = Okio.buffer(sink(sink));
+        }
+        //写入
+        requestBody.writeTo(bufferedSink);
+        //刷新
+        bufferedSink.flush();
+    }
+
+    private Sink sink(BufferedSink sink) {
+
+        return new ForwardingSink(sink) {
+            long bytesWritten = 0L;
+            long contentLength = 0L;
+            @Override
+            public void write(Buffer source, long byteCount) throws IOException {
+                super.write(source, byteCount);
+                if (contentLength==0){
+                    contentLength = contentLength();
+                }
+                bytesWritten += byteCount;
+                //回调
+                Message msg = Message.obtain();
+                msg.what = UPDATE;
+                msg.obj =  new ProgressModel(bytesWritten,contentLength,bytesWritten==contentLength);
+                myHandler.sendMessage(msg);
+            }
+        };
+    }
+
+
+}