Android 大文件切割与合并的实现代码
作者:_亻弋_石马_亻_生 发布时间:2023-05-25 21:58:58
标签:Android,大文件,切割,合并
前言:
由于公司的业务,硬生生的把ios开发的我,掰成了android!关于上传文件的需求处理,做了一个Java的简单封装 DocumentManagement 。其中集成了,检测文件,MD5加密,Base64加密/解码,针对文件Base64加密处理,获取文件后戳,切割文件,合并文件等方法。
亲测可切割与合并有效:视频、mp3、jpg、apk!还有很多没测,讲道理应该是都可以的。合并效果如图:
好了不扯皮了,直接上代码!注:以下代码仅供参考,如有想法请留言告知 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下载地址
来源:https://www.jianshu.com/p/8c38230aee8a


猜你喜欢
- 一、定义责任链模式(Chain of Responsibility Pattern):避免将一个请求的发送者与接受者耦合在一起,让多个对象都
- /// <summary> /// 遍历Co
- 一. 概述: Spinner是我们所熟悉的下拉框列表。与ListView类似,我们必须
- Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码。一、当两个并发线程访问同一个
- 用java的框架和面板的知识做的一个展示月食过程的小程序。这里的想法就是先把背景设置成黑色,然后画一个黄色的圆作为月亮,接着画一个黑色的圆,
- 本文实例讲述了Android编程中Tween动画和Frame动画实现方法。分享给大家供大家参考,具体如下:Animation主要有两种动画模
- 目录android_os_MessageQueue.cppLooper.cpp1.epoll基础知识介绍epoll工作流程分析案例2. po
- 一、opsForValue用法key:字符串,value:可以是任意对象Object(例如String、具体对象如自定义类Student等)
- Mybatis typeAlias配置1.定义别名<typeAliases> <ty
- 本篇紧接上一篇内容继续,还是从继承里的细节开始1.代码块初始化关于代码块的定义和使用因为之前已经进行过介绍,所以这里就不再赘述,我们所关注的
- android 点击EditText始终不弹出软件键盘场景描述:正常情况下,当点击EditText时,软键盘会弹出来。现在的要求
- 本文实例为大家分享了Android实现3D云标签效果的具体代码,供大家参考,具体内容如下一、自定义Viewpublic class TagC
- 1|0构造socket在【客户端/服务端】的通信模式中,客户端需要主动构造与服务器连接的 Socket,构造方法有以下几种重载形式:Sock
- 池塘里养:Object;一、设计与原理1、基础案例首先看一个基于common-pool2对象池组件的应用案例,主要有工厂类、对象池、对象三个
- 本文实例为大家分享了Unity shader实现遮罩效果的具体代码,供大家参考,具体内容如下效果:shader代码:Shader "
- 前言列表是移动应用中用得最多的组件了,我们也会经常对列表元素进行增加或删除操作,最简单的方法是列表数据变动后,直接 setStat
- 今天收到了Android Studio3.0更新推送,在升级过程中遇到几个问题,在这里把问题和解决方法记录下,方便要升级的童鞋。如果还有童
- 本文实例为大家分享了C语言实现一个扫雷小游戏的具体代码,供大家参考,具体内容如下一、全部源码//棋盘大小#define ROW 9#defi
- 什么是程序集?1.程序集(assembly)是一个及一个以上托管模块,以及一些资源文件的逻辑组合。2.程序集是组件复用,以及实施安全策略和版
- 介绍Java命令模式(Command Pattern)是一种行为型设计模式,它将请求封装成一个对象,从而使不同的请求可以进行参数化,并支持请