Java文件分片与合并

目录

1、文件分片

2、分片合并


1、文件分片

/**
 * 文件分片
 *
 * @param sourceFilePath    源文件路径
 * @param descDirPath       目标文件夹路径
 * @param sliceSize         分片大小(byte)
 */
public List<String> splitFile(String sourceFilePath, String descDirPath, long sliceSize) {
	if (ObjectUtils.isEmpty(sourceFilePath)) {
		throw new BusinessException("sourceFilePath is null, sourceFilePath = " + sourceFilePath);
	}
	if (ObjectUtils.isEmpty(descDirPath)) {
		throw new BusinessException("descDirPath is null, descDirPath = " + descDirPath);
	}
	File sourceFile = new File(sourceFilePath);
	if (!sourceFile.exists()) {
		throw new BusinessException("file is not exists, sourceFilePath = " + sourceFilePath);
	}
	if (sourceFile.isDirectory()) {
		throw new BusinessException("source is not file, sourceFilePath = " + sourceFilePath);
	}
	File descDir = new File(descDirPath);
	if (!descDir.exists()) {
		descDir.mkdirs();
	}

	List<String> sliceFilePath = new ArrayList<>();
	try (RandomAccessFile raf = new RandomAccessFile(sourceFile, "r")) {
		long length = raf.length();//文件的总长度
		long offSet = 0L;//初始化偏移量
		int index = 0;
		while ((length - offSet)/sliceSize != 0) {
			long begin = offSet;
			long end = begin + sliceSize;
			offSet = getWrite(sourceFilePath, descDirPath, index++, begin, end, sliceFilePath);
		}
		if (length - offSet > 0) {
			getWrite(sourceFilePath, descDirPath, index, offSet, length, sliceFilePath);
		}
	} catch (IOException e) {
		throw new BusinessException("file split error", e);
	}
	return sliceFilePath;
}
/**
 * 指定文件每一份的边界,写入不同文件中
 * @param sourceFilePath 源文件路径
 * @param index 源文件的顺序标识
 * @param begin 开始指针的位置
 * @param end 结束指针的位置
 * @return long
 */
private long getWrite(String sourceFilePath, String descDir, int index, long begin, long end, List<String> sliceFilePath){
	File sourceFile = new File(sourceFilePath);
	String sourceFileName = sourceFile.getName();
	String root = sourceFileName.substring(0, sourceFileName.lastIndexOf(".") + 1);
	String descFilePath = descDir + "/" + root + "_" + index + ".tmp";
	sliceFilePath.add(descFilePath);
	long endPointer = 0L;
	try (RandomAccessFile in = new RandomAccessFile(sourceFile, "r");
		 RandomAccessFile out = new RandomAccessFile(new File(descFilePath), "rw")) {

		//申明具体每一文件的字节数组
		byte[] b = new byte[1024];
		int n = 0;
		//从指定位置读取文件字节流
		in.seek(begin);
		//判断文件流读取的边界
		while(in.getFilePointer() <= end && (n = in.read(b)) != -1){
			//从指定每一份文件的范围,写入不同的文件
			out.write(b, 0, n);
		}
		//定义当前读取文件的指针
		endPointer = in.getFilePointer();
	} catch (Exception e) {
		e.printStackTrace();
	}

	return endPointer;
}

2、分片合并

/**
 * 文件合并
 *
 * @param mergeFiles          .tmp文件集合
 * @param descFilePath        合并后的文件地址
 */
public String mergeFile(List<String> mergeFiles, String descFilePath) {
	if (ObjectUtils.isEmpty(mergeFiles)) {
		throw new BusinessException("mergeFiles is null");
	}
	File file = new File(descFilePath);
	if (!file.getParentFile().exists()) {
		file.getParentFile().mkdirs();
	}
	try (RandomAccessFile raf = new RandomAccessFile(file, "rw")) {
		//开始合并文件,对应切片的二进制文件
		for (String mergeFile : mergeFiles) {
			//读取切片文件
			RandomAccessFile reader = new RandomAccessFile(new File(mergeFile), "r");
			byte[] b = new byte[1024];
			int n = 0;
			//先读后写
			while ((n = reader.read(b)) != -1) {//读
				raf.write(b, 0, n);//写
			}
		}
	} catch (FileNotFoundException ex) {
		throw (new BusinessException("file not found:", ex));
	} catch (IOException e) {
		e.printStackTrace();
	}
	String type = descFilePath.substring(descFilePath.lastIndexOf(".") + 1);
	if (ZIP.equals(type)) {
		try (InputStream inputStream = new FileInputStream(descFilePath)){
			//ZIP格式直接解压
			descFilePath = descFilePath.substring(0, descFilePath.lastIndexOf("."));
			unZip(inputStream, descFilePath);
			return descFilePath;
		} catch (FileNotFoundException ex) {
			throw (new BusinessException("file not found:", ex));
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	return descFilePath;
}

以上内容为个人学习理解,如有问题,欢迎在评论区指出。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值