使用Java歸檔檔案
作者:admin
分類:PHP, JAVA, .NET技術
時間:2016-05-12 10:15:53
點選量:1996
存檔放在一個作為一個單元的一個或多個檔案的集合。通常,在Java程式中,我們會遇到稱為JAR(Java歸檔)的歸檔檔案。這種類型的檔案對于每一個Java程式員都不陌生。歸檔檔案通常通過使用檔案歸檔軟體如WinZip,7-zip,tar等建立。這些類型的檔案特别可用于多個檔案存儲和作為單個單元的傳輸。檔案歸檔有時會采用資料壓縮和加密的方式。本文通過使用Java程式設計深入研究了一些與歸檔檔案工作相關的關鍵概念。
資料壓縮的概述
檔案檔案可以采用不同的資料編碼技術來減少一個檔案的内容所占位元組數。 有多種壓縮算法來減小檔案大小;通常它們有兩種類型: 無損和有損壓縮。 無損壓縮算法的工作不會産生任何資料損失,當資料檔案的大小被減少時。 另一方面,有損壓縮是假定丢失一些資訊是可接受的。 例如,當壓縮一個圖像檔案時,一些顔色的損失不會造成太大的視覺差異,但可顯著降低檔案大小。 這對于諸如圖像,視訊,等等類型的檔案是可接受的。 但是,這樣的有損壓縮并不對于包含産品資訊的檔案是可接受的。此時,我們需要應用無損資料壓縮技術,因為當被解壓縮時,我們需要的是不丢失任何資料的精确資訊。
例如,對于一個無損資料壓縮,一個字元串,如‘AAAAAABBBB’可被存儲為'6A4B';換言之,“六A和4 B的'。 儲存“6A4B”的空間比存儲字元重複序列的空間少得多。 這個簡單的技術被稱為運作長度算法(RLE)。 RLE可通過被稱為統計備援的方法,其通過計數器代替重複序列的字元進而減小檔案大小。 目前有損和無損資料壓縮的算法有很多種。 例如, Lempel-Ziv (LZ)算法的變量 - LZR(Lempel-Ziv-Renau)算法,其形成了一個基礎的ZIP檔案,LZW(Lempel-Ziv-Welch)在GIF圖像内使用。
編碼技術,如MP3,Vorbis和AAC都是有損的,而JPEG 2000, FLIF,等等都是無損的。 它們對于圖像或音頻/視訊壓縮是非常有用的,其丢失幾個比特位并不會影響整個内容,但肯定會降低一些品質,如果你比較挑剔微小的細節。試着聽一個MP3音頻和相同的檔案,以未壓縮音頻格式,如WAV,AIFF,AU,或PCM格式。
https://en.wikipedia.org/wiki/Data_compression
https://en.wikipedia.org/wiki/Lossless_compression
https://en.wikipedia.org/wiki/Audio_file_format
這個過程被反轉以獲得實際的資料内容時,被稱為解壓縮。
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLicmbw5iMhdjN2Y2YyADO5YjNzQzYwUmM0EWOjNWYxYWN1cTYx8CX0JXZ252bj91Ztl2Lc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
圖形1. 歸檔如何運作
在Java中壓縮資料
Java提供了兩個API類,被稱為Deflater和Inflater,在java.util.zip包内進行壓縮和解壓資料。這兩個類提供了Java的核心壓縮及解壓縮工具。執行這些類的方式如下。
建立一個Deflater執行個體
輸入字元串的位元組格式
調用finish()方法至輸入資料的信号終端
調用deflate()方法進行壓縮
調用end()方法來結束壓縮過程
同樣,資料恢複/解壓縮,請按照下列步驟操作:
建立一個Inflater執行個體
壓縮位元組作為輸入資料
調用inflate()方法進行解壓
調用end()方法來結束解壓過程
讓我們嘗試一個簡單的字元串。不要混淆:Deflater是壓縮和Inflater是解壓。
package org.mano.example;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.zip.DataFormatException;
import java.util.zip.Deflater;
import java.util.zip.Inflater;
public class ArchiveDemo {
public static void main(String[] args)
throws IOException, DataFormatException {
String inputData = "Lorem ipsum dolor sit amet,
consectetur adipiscing elit, "
+ "sed do eiusmod tempor incididunt ut labore et
dolore magna aliqua. "
+ "Ut enim ad minim veniam, quis nostrud exercitation
ullamco laboris "
+ "nisi ut aliquip ex ea commodo consequat. Duis aute
irure dolor in "
+ "reprehenderit in voluptate velit esse cillum dolore
eu fugiat nulla "
+ "pariatur. Excepteur sint occaecat cupidatat non
proidendecompressort,"
+ "sunt in culpa qui officia deserunt mollit anim id
est laborum.";
byte[] compressedByte = compress(inputData.getBytes(),
Deflater.BEST_COMPRESSION, false);
byte[] decompressedByte=decompress(compressedByte, false);
String outputData=new String(decompressedByte);
System.out.println("Input Data: " + inputData);
System.out.println("Uncompressed data length: "
+ inputData.getBytes().length);
System.out.println("Compressed data length: "
+ compressedByte.length);
System.out.println("Decompressed data length: "
+ decompressedByte.length);
System.out.println("Output Data: " + outputData);
}
public static byte[] decompress(byte[] input, boolean format)
throws IOException, DataFormatException {
Inflater inflater = new Inflater(format);
inflater.setInput(input);
ByteArrayOutputStream baout = new ByteArrayOutputStream();
byte[] buff = new byte[1024];
int count = 0;
while (!inflater.finished()) {
count = inflater.inflate(buff);
if ( count > 0)
baout.write(buff, 0, count);
}
inflater.end();
return baout.toByteArray();
}
public static byte[] compress(byte[] data, int compressionLevel,
boolean format) throws IOException {
Deflater deflater = new Deflater(compressionLevel, format);
deflater.setInput(data);
deflater.finish();
ByteArrayOutputStream baout = new ByteArrayOutputStream();
byte[] buff = new byte[1024];
int count = 0;
while (!deflater.finished()) {
count = deflater.deflate(buff);
if (count > 0)
baout.write(buff, 0, count);
}
deflater.end();
return baout.toByteArray();
}
}
以ZIP格式運作
假設我們有許多檔案被存檔于ZIP格式;我們可以使用java.util.zip包中的類,如ZipEntry,ZipInputStream,ZipOutputStream,以及ZipFile以ZIP檔案格式運作。
package org.mano.example;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.zip.Deflater;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
public class ArchiveDemo2 {
private static ZipOutputStream zout;
public static void main(String[] args)
throws IOException, FileNotFoundException {
String zipFile = "myzipfile.zip";
String[] files = { "myfile.txt, /home/mano/doc/file2.txt,
file3.png" };
zip(zipFile, files);
}
public static void zip(String zipFile, String[] files)
throws IOException, FileNotFoundException {
String currentDirectory = System.getProperty("user.dir");
zout = new ZipOutputStream(new
BufferedOutputStream(new FileOutputStream(zipFile)));
zout.setLevel(Deflater.BEST_COMPRESSION);
for (int i = 0; i < files.length; i++) {
File file = new File(files[i]);
if (!file.exists()) {
System.out.println("File " + file.getAbsolutePath()
+ " not found ");
System.out.println("Aborted.");
return;
}
ZipEntry ze = new ZipEntry(files[i]);
zout.putNextEntry(ze);
BufferedInputStream buffin = new BufferedInputStream(new
FileInputStream(files[i]));
byte[] buffer = new byte[1024];
int count = -1;
while ((count = buffin.read(buffer)) != -1) {
zout.write(buffer, 0, count);
}
buffin.close();
}
zout.closeEntry();
zout.close();
System.out.println("Output written to "
+ currentDirectory + File.separator + zipFile);
}
}
讀取ZIP格式檔案的内容
package org.mano.example;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
public class ArchiveDemo3 {
public static void main(String[] args) {
String zipFile = "myzipfile.zip";
String unziploc = "/home/mano/test";
unzip(zipFile, unziploc);
}
public static void unzip(String zipFile, String unziploc) {
try (ZipInputStream zin = new ZipInputStream(new
BufferedInputStream(new FileInputStream(zipFile)))) {
ZipEntry ze = null;
while ((ze = zin.getNextEntry()) != null) {
File file = new File(unziploc + File.separator
+ ze.getName());
File root = file.getParentFile();
if (!root.exists()) root.mkdirs();
file.createNewFile();
BufferedOutputStream buffout = new BufferedOutputStream(
new FileOutputStream(unziploc + File.separator
+ ze.getName()));
byte[] buffer = new byte[1024];
int count = -1;
while ((count = zin.read(buffer)) != -1) {
buffout.write(buffer, 0, count);
}
buffout.close();
}
System.out.println("Contents extracted to " + (new
File(unziploc)).getAbsolutePath());
} catch (IOException e) {
e.printStackTrace();
}
}
}
結論
Java API已有一些類來處理一些常見的其他歸檔檔案格式,如GZIP檔案和JAR檔案。歸檔檔案基本上包含目錄結構的中繼資料資訊,錯誤檢測和恢複資訊等等。java.util.zip包提供了一些優秀的實用工具類以在存檔支援之外處理校驗。
來源: Developer.com