一、GzipInputStream解壓
在進行文件傳輸或存儲時,文件的壓縮可以有效的減少帶寬的使用和存儲空間的佔用。其中,GZIP壓縮是一種強大的壓縮方式。
GzipInputStream是Java中實現對GZIP文件進行解壓的核心類,通過其解壓方法可以將壓縮文件解壓為原始文件。
public class GZipDemo {
public void unZip() throws IOException {
String inputFilePath = "example.gz";
String outputFilePath = "example.txt";
try ( GZIPInputStream gzipInputStream = new GZIPInputStream(
new FileInputStream(inputFilePath))) {
FileOutputStream fileOutputStream = new FileOutputStream(outputFilePath);
byte[] buffer = new byte[1024];
int length;
while ((length = gzipInputStream.read(buffer)) > 0) {
fileOutputStream.write(buffer, 0, length);
}
}
}
}
以上代碼演示了如何通過GzipInputStream解壓.gz文件,最終將解壓後的文件存儲為example.txt。
二、GzipInputStream讀取文件內存溢出
當壓縮文件非常大時,可能會導致內存溢出。為了避免這種情況的發生,我們可以使用GzipInputStream讀取文件時,每次只讀取一部分數據。
public void unZip() throws IOException {
String inputFilePath = "example.gz";
String outputFilePath = "example.txt";
try ( GZIPInputStream gzipInputStream = new GZIPInputStream(
new FileInputStream(inputFilePath))) {
try (FileOutputStream fileOutputStream = new FileOutputStream(outputFilePath)) {
int bufferSize = 1024;
byte[] buffer = new byte[bufferSize];
int len;
while ((len = gzipInputStream.read(buffer, 0, bufferSize)) != -1) {
fileOutputStream.write(buffer, 0, len);
}
fileOutputStream.flush();
}
}
}
按照以上方式讀取數據,我們可以有效地避免內存溢出的問題。
三、GzipInputStream用法
以下為GzipInputStream的常用方法:
- public GZIPInputStream(InputStream in):使用默認緩衝區大小創建GzipInputStream對象
- public GZIPInputStream(InputStream in, int size):使用指定緩衝區大小創建GzipInputStream對象
- public int read(byte b[], int off, int len) throws IOException:從輸入流中讀取b.length個字節到字節數組b中,並返回實際讀取的字節數
- public void close() throws IOException:關閉輸入流
四、GzipInputStream耗CPU
由於GzipInputStream需要對壓縮文件進行解壓,因此會消耗一定的CPU資源。當需要處理大量壓縮文件時,我們可以考慮使用多線程並發處理的方式來提高效率。
以下為使用多線程解壓方式的示例代碼:
public void unzipFiles(List fileList) {
ExecutorService executorService = Executors.newFixedThreadPool(5);
List<Callable> calls = new ArrayList();
for (File file : fileList) {
calls.add(() -> {
String filePath = file.getAbsolutePath();
String outPath = "out" + File.separator + file.getName().substring(0, file.getName().length() - 3);
try (GZIPInputStream gzipInputStream = new GZIPInputStream(new FileInputStream(file));
BufferedInputStream in = new BufferedInputStream(gzipInputStream);
BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(outPath))) {
byte[] buffer = new byte[1024];
int len;
while ((len = in.read(buffer)) > 0) {
out.write(buffer, 0, len);
}
} catch (IOException e) {
e.printStackTrace();
}
return true;
});
}
try {
List<Future> futures = executorService.invokeAll(calls);
for (Future future : futures) {
boolean result = future.get();
System.out.println("result : " + result);
}
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
} finally {
executorService.shutdown();
}
}
上述代碼演示了如何使用線程池的方式進行多線程解壓,通過將解壓任務提交給線程池去處理,可以有效提升解壓的效率。
五、GzipInputStream解壓gz文件
GzipInputStream在解壓.gzip文件時表現出色。我們可以使用以下代碼來解壓.gzip文件:
public static void gzipInputStreamByFile(File file) throws IOException {
String inputFile = file.getAbsolutePath();
String outputFile = inputFile.substring(0, inputFile.lastIndexOf("."));
try (GZIPInputStream gzipInputStream = new GZIPInputStream(new FileInputStream(file));
FileOutputStream fileOutputStream = new FileOutputStream(outputFile);
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(fileOutputStream, StandardCharsets.UTF_8);
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(gzipInputStream))) {
String line;
while ((line = bufferedReader.readLine()) != null) {
outputStreamWriter.write(line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
以上代碼演示了如何使用GzipInputStream解壓.gzip文件,並將解壓後的文件按行寫入到新建的文件中。
六、GzipInputStream解壓成多個文件
有時候,我們需要將一個壓縮文件解壓為多個文件。以下是如何使用GzipInputStream將壓縮文件解壓為多個文件的代碼:
public static void unzipBySize(File file, long maxSize) throws IOException {
byte[] buffer = new byte[1024];
long totalSize = 0L;
int count = 0;
String filePath = file.getAbsolutePath();
try (GZIPInputStream gzipInputStream = new GZIPInputStream(new FileInputStream(file));
FileInputStream fileInputStream = new FileInputStream(file);
ObjectInputStream objectInputStream = new ObjectInputStream(gzipInputStream);
DataInputStream dataInputStream = new DataInputStream(gzipInputStream);
BufferedInputStream in = new BufferedInputStream(gzipInputStream)) {
String line;
while ((line = new BufferedReader(new InputStreamReader(in)).readLine()) != null) {
filePath += "_out_" + ++count;
try (FileOutputStream fileOutputStream = new FileOutputStream(filePath);
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(fileOutputStream, StandardCharsets.UTF_8);
BufferedWriter bufferedWriter = new BufferedWriter(outputStreamWriter)) {
while (totalSize < maxSize) {
int len = in.read(buffer);
if (len == -1) {
break;
}
bufferedWriter.write(new String(buffer, 0, len));
bufferedWriter.newLine();
totalSize += len;
}
}
totalSize = 0L;
}
} catch (IOException e) {
e.printStackTrace();
}
}
我們通過將解壓後的文件寫入到一個新的文件中,以達到將壓縮文件解壓成多個文件的目的。
七、GzipInputStream讀取文件不全
在使用GzipInputStream讀取文件時,可能會出現文件讀取不全的情況。這種情況一般是因為文件格式不正確或壓縮數據被損壞等原因導致。我們可以在程序中添加異常處理機制,當讀取文件不全時可以做出相應的處理。
public static void readFully(InputStream is, byte[] buffer, int len) throws IOException {
int total = 0;
while (total < len) {
int result = is.read(buffer, total, len - total);
if (result == -1) {
throw new EOFException("Unexpected end of GZIP input stream");
}
total += result;
}
}
public static void unzip(InputStream input, OutputStream output) throws IOException {
try (GZIPInputStream in = new GZIPInputStream(input)) {
byte[] buffer = new byte[1024];
int len;
while ((len = in.read(buffer)) != -1) {
output.write(buffer, 0, len);
}
} catch (IOException e) {
e.printStackTrace();
input.close();
output.close();
}
}
以上代碼演示了如何在GzipInputStream讀取文件時添加異常處理機制,當文件讀取不全時可以及時進行處理。
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/187721.html
微信掃一掃
支付寶掃一掃