檔案壓縮:
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,測試結果如圖:
壓縮結果以及壓縮時間:
![]()
利用Java的I/O流實作圖檔的壓縮以及解壓 解壓結果以及解壓時間:![]()
利用Java的I/O流實作圖檔的壓縮以及解壓 ![]()
利用Java的I/O流實作圖檔的壓縮以及解壓 ![]()
利用Java的I/O流實作圖檔的壓縮以及解壓