一、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/n/187721.html
微信扫一扫
支付宝扫一扫