Android 大文件切割与合并

作者: _亻弋_石马_亻_生 | 来源:发表于2018-08-28 18:05 被阅读120次

    前言:

    由于公司的业务,硬生生的把ios开发的我,掰成了android!关于上传文件的需求处理,做了一个Java的简单封装 DocumentManagement 。其中集成了,检测文件,MD5加密,Base64加密/解码,针对文件Base64加密处理,获取文件后戳,切割文件,合并文件等方法。

    亲测可切割与合并有效:视频、mp3、jpg、apk!还有很多没测,讲道理应该是都可以的。合并效果如图:
    0025EFD3E1691807BA4BBC2A5E8CA33F.png
    好了不扯皮了,直接上代码!注:以下代码仅供参考,如有想法请留言告知
    • DocumentManagement 使用方法如下:
                              //文件
                                File file = new File(strPath);
    
                                documentManagement.log("开始——汪汪汪汪");
                                //切割文件
                                documentManagement.getSplitFile(file,1*1024*1024 );
    
                                //合并文件
                                String merFileName = "gsplay";//自定义合并文件名字
                                //创建合并文件路径
                                String filePath = Environment.getExternalStorageDirectory().getPath()+"/"+merFileName;
    
                                documentManagement.merge(filePath,file,1*1024*1024);
                                documentManagement.log("结束——汪汪汪汪");
    
    • Java获取文件后缀
     /**
         * 获取文件后缀名 例如:.mp4 /.jpg /.apk
         * @param file 指定文件
         * @return String 文件后缀名
         */
        public static String suffixName (File file){
            String fileName=file.getName();
            String fileTyle=fileName.substring(fileName.lastIndexOf("."),fileName.length());
            return fileTyle;
        }
    
    • 文件按设定的大小进行切割
     /**
         * 文件分割方法
         * @param targetFile 分割的文件
         * @param cutSize 分割文件的大小
         * @return int 文件切割的个数
         */
        public static int getSplitFile(File targetFile ,long cutSize ) {
    
            //计算切割文件大小
            int count = targetFile.length() % cutSize == 0 ? (int) (targetFile.length() / cutSize) :
                    (int) (targetFile.length() / cutSize + 1);
    
            RandomAccessFile raf = null;
            try {
                //获取目标文件 预分配文件所占的空间 在磁盘中创建一个指定大小的文件   r 是只读
                raf = new RandomAccessFile(targetFile, "r");
                long length = raf.length();//文件的总长度
                long maxSize = length / count;//文件切片后的长度
                long offSet = 0L;//初始化偏移量
    
                for (int i = 0; i < count - 1; i++) { //最后一片单独处理
                    long begin = offSet;
                    long end = (i + 1) * maxSize;
                    offSet = getWrite(targetFile.getAbsolutePath(), i, begin, end);
                }
                if (length - offSet > 0) {
                    getWrite(targetFile.getAbsolutePath(), count-1, offSet, length);
                }
    
            } catch (FileNotFoundException e) {
    //            System.out.println("没有找到文件");
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    raf.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return count;
        }
        /**
         * 指定文件每一份的边界,写入不同文件中
         * @param file 源文件地址
         * @param index 源文件的顺序标识
         * @param begin 开始指针的位置
         * @param end 结束指针的位置
         * @return long
         */
        public static long getWrite(String file,int index,long begin,long end ){
    
            long endPointer = 0L;
    
            String a=file.split(suffixName(new File(file)))[0];
    
            try {
                //申明文件切割后的文件磁盘
                RandomAccessFile in = new RandomAccessFile(new File(file), "r");
                //定义一个可读,可写的文件并且后缀名为.tmp的二进制文件
                //读取切片文件
                File mFile = new File(a + "_" + index + ".tmp");
                //如果存在
                if (!isFileExist(mFile)) {
                    RandomAccessFile out = new RandomAccessFile(mFile, "rw");
                    //申明具体每一文件的字节数组
                    byte[] b = new byte[1024];
                    int n = 0;
                    //从指定位置读取文件字节流
                    in.seek(begin);
                    //判断文件流读取的边界
                    while ((n = in.read(b)) != -1 && in.getFilePointer() <= end) {
                        //从指定每一份文件的范围,写入不同的文件
                        out.write(b, 0, n);
                    }
    
                    //定义当前读取文件的指针
                    endPointer = in.getFilePointer();
                    //关闭输入流
                    in.close();
                    //关闭输出流
                    out.close();
                }else {
                    //不存在
    
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            return endPointer - 1024;
        }
    
    • 文件合并
    /**
         * 文件合并
         * @param fileName 指定合并文件
         * @param targetFile 分割前的文件
         * @param cutSize 分割文件的大小
         */
        public static void merge(String fileName,File targetFile ,long cutSize) {
    
    
            int tempCount  = targetFile.length() % cutSize == 0 ? (int) (targetFile.length() / cutSize) :
                    (int) (targetFile.length() / cutSize + 1);
            //文件名
            String a=targetFile.getAbsolutePath().split(suffixName(targetFile))[0];
    
            RandomAccessFile raf = null;
            try {
                //申明随机读取文件RandomAccessFile
                raf = new RandomAccessFile(new File(fileName+suffixName(targetFile)), "rw");
                //开始合并文件,对应切片的二进制文件
                for (int i = 0; i < tempCount; i++) {
                    //读取切片文件
                    File mFile = new File(a + "_" + i + ".tmp");
                    //
                    RandomAccessFile reader = new RandomAccessFile(mFile, "r");
                    byte[] b = new byte[1024];
                    int n = 0;
                     //先读后写
                     while ((n = reader.read(b)) != -1) {//读
                         raf.write(b, 0, n);//写
                     }
                     //合并后删除文件
                    isDeleteFile(mFile);
                     //日志
                    log(mFile.toString());
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try {
                    raf.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    
    

    DocumentManagement_Dome_Git下载地址

    相关文章

      网友评论

        本文标题:Android 大文件切割与合并

        本文链接:https://www.haomeiwen.com/subject/xveqwftx.html