一、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-hk/n/187721.html