文件压缩:
public class TestMerge {
public static void merge(String srcFiles, String destFilePath) {
//判断原文件路径是否为空
if (srcFiles == null) {
throw new IllegalArgumentException(srcFiles + " must be not null");
}
//创建目标文件夹,并且判断目标文件夹是否存在
File destFile = new File(destFilePath);
if (!destFile.exists()) {
boolean effect = destFile.mkdirs();
if (!effect) {
throw new IllegalArgumentException(destFile + " create failed");
}
}
//获取原文件夹中所有的文件
File[] files = listAllFiles(srcFiles);
for (File src : files) {
//如果文件格式不是jpg或者png,就不参与文件合并
if (!src.getName().endsWith("jpg") && !src.getName().endsWith("png")) {
continue;
}
//记录每个参与合并的文件的字节长度
int length = (int) src.length();
//进行文件传入和目的文件的传出
try (FileInputStream in = new FileInputStream(src);
FileOutputStream out = new FileOutputStream(new File(destFile, "mergeP2.jpg"), true)) {
//将每个参与合并的图片文件的长度加在文件字节前,用于记录参与合并的文件长度,并且在解压文件时起到指示此文件解压完成的作用
//这里需要将文件的长度转换成byte数组,再传入目的文件中
//length -> byte[] 82(int) -> 32(bit)
for (int i = 0; i < trans(length).length; i++) {
// System.out.println(trans(length)[i]);
out.write(trans(length)[i]);
}
//读取原文件中的字节内容
byte[] buff = new byte[1024];
int len = -1;
while ((len = in.read(buff)) != -1) {
out.write(buff, 0, len);
}
out.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
}
//实现int类型转换为byte数组
public static byte[] trans(int data) {
//int转换成byte[] 不需要 & 0xFF
//0xFF是字面量:00000000 00000000 00000000 11111111
byte[] ret = new byte[4];
ret[0] = (byte) (data >> 24);
ret[1] = (byte) (data >> 16);
ret[2] = (byte) (data >> 8);
ret[3] = (byte) data;
return ret;
}
//实现byte数组转换成int类型
public static int byteArrayToInt(byte[] buff) {
//byte[] 转换成int 必须 & 0xFF
int values = 0;
for (int i = 0; i < 4; i++) {
int shift = (3 - i) * 8;
values += (buff[i] & 0xFF) << shift;
}
return values;
}
//用来显示原文件夹下所有的文件,简化添加图片文件的步骤
public static File[] listAllFiles(String srcFilePath) {
File srcFile = new File(srcFilePath);
if (srcFile.isFile()) {
return new File[]{srcFile};
}
return srcFile.listFiles();
}
//测试
public static void main(String[] args) {
// String[] srcFiles = {"D:" + File.separator + "TestCode" + File.separator + "iotest" + File.separator + "data-a.txt",
// "D:" + File.separator + "TestCode" + File.separator + "iotest" + File.separator + "data-b.txt",
// "D:" + File.separator + "TestCode" + File.separator + "iotest" + File.separator + "data-c.txt"};
// String destFilePath = "D:" + File.separator + "TestCode" + File.separator + "iotest" + File.separator + "data.txt";
// merge(srcFiles, destFilePath);
String srcFiles = "D:" + File.separator + "TestCode" + File.separator + "iotest" + File.separator + "spiltP";
String destFilePath = "D:" + File.separator + "TestCode" + File.separator + "iotest" + File.separator + "mergePicture";
long start = System.currentTimeMillis();
merge(srcFiles, destFilePath);
long end = System.currentTimeMillis();
System.out.println(end-start);
}
}
文件解压:
public class TestSplit {
public static void splitFile(String srcFilePath, String destFilesPath) {
//判断原文件路径是否存在
if (srcFilePath.isEmpty()) {
throw new IllegalArgumentException(srcFilePath + "must be not null");
}
//创建原文件
File srcFile = new File(srcFilePath);
//count用来记录解压得到的文件个数,并用于文件命名
int count = 1;
//创建目的文件夹
File destFile = new File(destFilesPath);
//判断目的文件夹是否存在
if (!destFile.exists()) {
destFile.mkdirs();
}
//进行文件传输
try (FileInputStream in = new FileInputStream(srcFile)) {
while (true) {
//首先读取压缩文件中的前4个字节,这4个字节记录了第一个解压出的文件长度
byte[] data = new byte[4];
int length = in.read(data);
if (length != 4) {
break;
}
//创建解压出的文件
FileOutputStream out = new FileOutputStream(new File(destFile, "p" + (count++) + ".jpg"));
//将压缩文件中的前四个字节记录的值转换成int类型的文件长度值
int fileLen = TestMerge.byteArrayToInt(data);
int len = -1;
//创建byte数组,数组长度为文件长度值
byte[] buff = new byte[fileLen];
len = in.read(buff);
//判断文件是否读取完
if (len != -1 && len == buff.length) {
//buff -> file
out.write(buff, 0, len);
out.flush();
out.close();
continue;
}
if (len == -1) {
break;
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
//测试
public static void main(String[] args) {
String directory = "D:" + File.separator + "TestCode" + File.separator + "iotest" + File.separator;
String srcFilePath = directory + "mergePicture"+File.separator+"mergeP2.jpg";
String destFilesPath = directory + "b";
long start = System.currentTimeMillis();
splitFile(srcFilePath, destFilesPath);
long end = System.currentTimeMillis();
System.out.println(end-start);
}
}
运行结果:
测试用例中,合并了87个文件图片,总共大小为328389KB,测试结果如图:
压缩结果以及压缩时间:
解压结果以及解压时间: