JAVA處理字符串壓縮以及文件壓縮

字符串壓縮:

之前在做Android客戶端開發的時候,需要請求一個字典類型的http請求接口,由於接口json數據過大,達到6M,當時建議後端對接口返回的json數據邏輯進行處理,在服務端將json串壓縮,然後在客戶端進行解壓,最後在將數據顯示在客戶端。

Java實現字符串壓縮API:

壓縮算法有多種,我說知道和接觸有java I/O自帶的zip和gzip兩種方式,此次的壓縮和解壓用到的主要就是GZIPOutputStream和GZIPInputStream類,看一下例子:

字符串壓縮代碼:

public static String compress(String source) {
        ByteArrayOutputStream bos = new ByteArrayOutputStream();

        try {
            GZIPOutputStream gos = new GZIPOutputStream(bos);
            gos.write(source.getBytes("ISO-8859-1"));
            gos.close();
            return bos.toString("ISO-8859-1");
        } catch (IOException var3) {
            System.out.println(var3.getStackTrace().toString());
            return source;
        }
}

字符串解壓代碼:

/****
	 * @Method compress  字符串解壓方法
	 * @author source 需要傳入待解壓的字符串
	 * 返回值   返回解壓後的字符串
	 ****/
    public static String uncompress(String source) {
        if (source != null && source.length() != 0) {
            try {
                ByteArrayOutputStream bos = new ByteArrayOutputStream();
                ByteArrayInputStream bis = new ByteArrayInputStream(source.getBytes("ISO-8859-1"));
                GZIPInputStream gis = new GZIPInputStream(bis);
                byte[] data = new byte[1024];

                for(int len = gis.read(data); len != -1; len = gis.read(data)) {
                    bos.write(data, 0, len);
                }

                return bos.toString();
            } catch (IOException var6) {
            	System.out.println(var6.getStackTrace().toString());
                return source;
            }
        } else {
            return source;
        }
    }

測試代碼:

public static void main(String[] args) {
		// 字符串超過一定的長度  
        String str = "ggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggfdgfdgf"
        		+ "ggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggg"
        		+ "gggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggABCdef123中文~!@#$%^&*()_+{fd}"
        		+ ";/1111111111111111111111111AAAAAAAAAAAJDLFJDLFJDLFJLDFFFFJEIIIIIIIIIIFJJJJJJJJJJJJALLLLLLLLLLLLLLLLLLLLLLdddddddddddddddddfdfdfdfdfdfdd"
        		+ "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddessdfrdfdfd"
        		+ "ddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd"
        		+ "ddddddddddddddddddddddddddddddddddddddddddddddddddddddgfgggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggf"
        		+ "ddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd"
        		+ "ddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd"
        		+ "ddddddddddddddddddddddddddddddddddddddddddddggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggg" +  
                "LLppppppppppppppppppppppppppppppppppppppppp===========================------------------------------iiiiiiiiiiiiiiiiiiiiiiiggggggggggggg";
        
        
        //字符串原始長度處理
        String originalStr = str;
        System.out.println("原始的字符串長度:" + originalStr.length());
        
        //字符串壓縮狀態處理
        String compressStr = compress(originalStr);
        System.out.println("壓縮的字符串長度:" + compressStr.length());
        
        //字符串解壓方法以及測試解壓後字符串長度
        String uncompress = uncompress(compressStr);
        System.out.println("解壓後的字符串長度:" + uncompress.length());
        
        //字符串壓縮率
        float rate = (float)compressStr.length() / uncompress.length();
        System.out.println("字符串壓縮率:" + rate);
        
        if(originalStr.equals(uncompress)){
        	System.out.println("解壓後的字符串和原始的字符串長度一樣");
        }
        
	}

控制檯打印輸出結果:

原始的字符串長度:1474

壓縮的字符串長度:136

解壓後的字符串長度:1474

字符串壓縮率:0.09226594

如圖通過調研compress壓縮方法將原始字符串壓縮,原始字符串的長度爲1474個字節,壓縮後字符串大小變爲136個字節,字符串的壓縮率達到91%。

 

Java代碼實現文件壓縮與解壓:

api說明:

1:添加ZipTools包(主要解決中文路徑壓縮解壓亂碼問題)

2:文件壓縮需要用到的類 ZipOutputStream(zip文件壓縮需要用到的類)

3:ZipEntry 壓縮文件的子文件對象,用於保存壓縮文件中文件及其文件夾的一個實列

4:ZipFile 壓縮文件的實列,用於zip的解壓操作

 

文件壓縮相關代碼:

	/****
	 * 
	 * @Method createZipStream 創建ZIP輸出流實例
	 * @param filePath 需要壓縮的文件以及路徑
	 * @param fileOutPath 生成壓縮的文件以及路徑
	 * 
	 ****/
	public static void createZipStream(String filePath, String fileOutPath) throws IOException{
		OutputStream os = new FileOutputStream(fileOutPath);//根據壓縮的文件路徑創建要輸出的文件
		CheckedOutputStream cos = new CheckedOutputStream(os, new CRC32());//檢查輸出流,採用crc算法,保證文件的一致性
		ZipOutputStream zos = new ZipOutputStream(cos);//定義zip文件輸出流
		zos.setEncoding("GBK");//設置編碼格式,防止中文亂碼
		File file = new File(filePath);//需要壓縮的文件以及文件夾對象
		compressFile(zos,file);
		zos.close();
		cos.close();
		os.close();
		System.out.println("壓縮文件完成");
	}



	/****
	 * @Method compressFile
	 * @param ZipOutputStream zip文件輸出流
	 * @param File 要壓縮的文件對象
	 ****/
	public static void compressFile(ZipOutputStream zos, File file) throws IOException{
		String fp = file.getPath().substring(3,file.getPath().length());//去掉盤符
		if(file.isDirectory()){//如果是文件目錄,添加當前文件夾到zip文件流中
			zos.putNextEntry(new ZipEntry(fp + File.separator));
			for(File f: file.listFiles()){
				compressFile(zos, f);
			}
		}else{//如果是文件目錄,添加當前文件到zip文件流中
			System.out.println("正在壓縮文件:"+file.getPath());
			zos.putNextEntry(new ZipEntry(fp));
			InputStream is = new FileInputStream(file.getPath());//用字節方式讀取文件
			BufferedInputStream bis = new BufferedInputStream(is);//創建一個緩存區
			byte [] b = new byte[1024];
			//將讀取的字節寫到zip文件流中
			while (bis.read(b) != -1) {
				zos.write(b);
			}
			bis.close();
			is.close();
		}
	}


測試函數以及返回示例:
	public static void main(String[] args) throws IOException {
		
		createZipStream(filePath,fileOutPath);
		
//		unCompressFile(fileOutPath);
		
	}

打印壓縮文件過程:

正在壓縮文件:D:\MyDrivers\backup\dgsetup.exe

正在壓縮文件:D:\MyDrivers\backup\driverlist.mf

正在壓縮文件:D:\MyDrivers\backup\Realtek PCIe GBE Family Controller\rt640x64.inf_amd64_98de0ddb0966f29b\rt640x64.inf

正在壓縮文件:D:\MyDrivers\backup\Realtek PCIe GBE Family Controller\rt640x64.inf_amd64_98de0ddb0966f29b\rt640x64.PNF

正在壓縮文件:D:\MyDrivers\backup\Realtek PCIe GBE Family Controller\rt640x64.inf_amd64_98de0ddb0966f29b\rt640x64.sys

壓縮文件完成

文件解壓相關函數:

/***
	 * 
	 * @Method unCompressFile
	 * @param filePath 需要解壓的文件路徑
	 *
	 ***/
	public static  void unCompressFile(String  filePath) throws IOException{
		File file = new File(filePath);
		if(!file.exists()){
			System.out.println("當前壓縮文件不存在");
			return;
		}
		ZipFile zipFile = new ZipFile(file.getPath(),"GBK");
		
		for(Enumeration<ZipEntry> enumeration = zipFile.getEntries();enumeration.hasMoreElements();){//循環獲取zip文件壓縮實例
			
			ZipEntry zipEntry = enumeration.nextElement();//獲取元素
			//如果是空文件不解壓
			if(!zipEntry.getName().equals(File.separator)){
				String path = "D:\\" + zipEntry.getName();
				System.out.println("文件名:" + path);
				int len = path.length();
				//創建解壓目錄
				if(path.substring(len - 1, len).equals("\\")){
					File createFile = new File(path);
					if(!createFile.exists()){
						createFile.mkdirs();//如果當前文件不存在,則創建解壓目錄
					}
				}else{
					//創建解壓後的文件
					OutputStream os = new FileOutputStream(new File(path));
					BufferedOutputStream bos = new BufferedOutputStream(os);//帶緩衝的寫出流
					InputStream is = zipFile.getInputStream(zipEntry);//讀取元素
					BufferedInputStream bis = new BufferedInputStream(is);
					CheckedInputStream cis = new CheckedInputStream(bis, new CRC32());//檢查讀取流,用CRC算法檢查文件是否一致性
					byte[] b = new byte[1024];//字節數組,每次讀取1024個字節
					//循環讀取解壓文件的值,將zip流寫入新文件中
					while (cis.read(b) != -1) {
						bos.write(b);
					}
					cis.close();
					bis.close();
					is.close();
					bos.close();
					os.close();
				}
			}else{
				System.out.println("目錄名:" + zipEntry.getName());
			}
		}
		System.out.println("文件解壓結束");
		
	}

測試解壓方法:
public static void main(String[] args) throws IOException {
		
//		createZipStream(filePath,fileOutPath);
		
		unCompressFile(fileOutPath);
		
	}

打印解壓文件結果:

文件名:D:\MyDrivers\backup\

文件名:D:\MyDrivers\update\

文件名:D:\MyDrivers\backup\dgsetup.exe

文件名:D:\MyDrivers\backup\Realtek PCIe GBE Family Controller\rt640x64.inf_amd64_98de0ddb0966f29b\

文件名:D:\MyDrivers\software\disapp\

文件名:D:\MyDrivers\backup\Realtek PCIe GBE Family Controller\rt640x64.inf_amd64_98de0ddb0966f29b\rt640x64.inf

文件名:D:\MyDrivers\backup\Realtek PCIe GBE Family Controller\

文件名:D:\MyDrivers\backup\Realtek PCIe GBE Family Controller\rt640x64.inf_amd64_98de0ddb0966f29b\rt640x64.PNF

文件名:D:\MyDrivers\backup\driverlist.mf

文件名:D:\MyDrivers\

文件名:D:\MyDrivers\backup\Realtek PCIe GBE Family Controller\rt640x64.inf_amd64_98de0ddb0966f29b\rt640x64.sys

文件名:D:\MyDrivers\hotfix\

文件名:D:\MyDrivers\software\

文件解壓結束

自己封裝的字符串壓縮和文件壓縮庫:

項目目錄結構截圖如下:

java_zip.jar包是我封裝的字符串和文件壓縮jar,slf4j-api-1.7.21.jar,slf4j-nop-1.7.2.jar爲代碼依賴的日誌包,ziptools.jar爲JavaApi  zip防止中文亂碼開發的包。

Api演示代碼如下:

public static String filePath = "D:/MyDrivers/";
	public static String fileOutPath = "D:/MyDrivers.zip";
	
	//在lib文件中有一個Java_zip.jar
	public static void main(String[] args) {
		// 字符串超過一定的長度  
        String str = "ggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggfdgfdgf"
        		+ "ggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggg"
        		+ "gggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggABCdef123中文~!@#$%^&*()_+{fd}"
        		+ ";/1111111111111111111111111AAAAAAAAAAAJDLFJDLFJDLFJLDFFFFJEIIIIIIIIIIFJJJJJJJJJJJJALLLLLLLLLLLLLLLLLLLLLLdddddddddddddddddfdfdfdfdfdfdd"
        		+ "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddessdfrdfdfd"
        		+ "ddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd"
        		+ "ddddddddddddddddddddddddddddddddddddddddddddddddddddddgfgggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggf"
        		+ "ddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd"
        		+ "ddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd"
        		+ "ddddddddddddddddddddddddddddddddddddddddddddggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggg" +  
                "LLppppppppppppppppppppppppppppppppppppppppp===========================------------------------------iiiiiiiiiiiiiiiiiiiiiiiggggggggggggg";
        System.out.println("字符串初始長度:" + str.length());
		String compressstr = GzipUtils.compress(str);
		System.out.println("壓縮後字符串長度:" + compressstr.length());
		String uncompress = GzipUtils.uncompress(compressstr);
		System.out.println("解壓後字符串長度:" + uncompress.length());
		
		//壓縮文件
//		ZipUtil.pack(new File(filePath), new File(fileOutPath));
		
		//解壓文件
		ZipUtil.unpack(new File(fileOutPath), new File(filePath));

項目Demo地址下載:

https://download.csdn.net/download/zhangmingziliao/10969290

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章