分享一个有趣的Java压缩与解压:ZipUtils类解析

时间:2024-10-13 07:22:51

在数字世界里,数据压缩就像是一门艺术,它能让信息更高效地传递。今天,我们要探索的是一个名为`ZipUtils`的Java类,它用神奇的魔法将字符串变小,也能将它们恢复原状。这不仅是技术,更是对效率的追求。

1,先放代码:

package com.sun.tool;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;

@Slf4j
public class ZipUtils {

    private static final String DEFAULT_ENCODING = "UTF-8";

    /**
     * 使用gzip进行压缩
     */
    public static String gzip(String primStr) {
        if (primStr == null || primStr.length() == 0) {
            return primStr;
        }
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        String result = null;
        GZIPOutputStream gzip = null;
        try {
            gzip = new GZIPOutputStream(out);
            gzip.write(primStr.getBytes(DEFAULT_ENCODING));
            gzip.finish();
            result = new String(new Base64().encode(out.toByteArray()), DEFAULT_ENCODING);
        } catch (IOException e) {
            log.error("ZipUtils.gzip.error", e);
            throw new RuntimeException(e);
        } finally {
            if (gzip != null) {
                try {
                    gzip.close();
                } catch (IOException e) {
                    log.error("ZipUtils.gzip.close.error", e);
                }
            }
        }
        return result;

    }

    /**
     * 使用gzip进行解压缩
     */
    public static String unGzip(String compressedStr) {
        if (compressedStr == null) {
            return null;
        }
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        ByteArrayInputStream in = null;
        GZIPInputStream gzipIn = null;
        byte[] compressed;
        String decompressed = null;
        try {
            compressed = new Base64().decode(compressedStr.getBytes(DEFAULT_ENCODING));
            in = new ByteArrayInputStream(compressed);
            gzipIn = new GZIPInputStream(in);
            byte[] buffer = new byte[1024];
            int offset;
            while ((offset = gzipIn.read(buffer)) != -1) {
                out.write(buffer, 0, offset);
            }
            decompressed = out.toString(DEFAULT_ENCODING);
        } catch (IOException e) {
            log.error("ZipUtils.unGzip.error", e);
        } finally {
            if (gzipIn != null) {
                try {
                    gzipIn.close();
                } catch (IOException e) {
                    log.error("ZipUtils.unGzip.close.error", e);
                }
            }
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                    log.error("ZipUtils.unGzip.in.close.error", e);
                }
            }
            if (out != null) {
                try {
                    out.close();
                } catch (IOException e) {
                    log.error("ZipUtils.unGzip.out.close.error", e);
                }
            }
        }
        return decompressed;
    }

}

2,下面是解释:

```java
@Slf4j
public class ZipUtils {
```
首先,我们看到这个类被`@Slf4j`注解加持,这意味着它拥有了一个名叫`log`的魔法日志助手,用来记录任何异常情况。

```java
    private static final String DEFAULT_ENCODING = "UTF-8";
```
这里定义了一个默认的编码方式`DEFAULT_ENCODING`,它告诉我们,无论何时处理字符串,都使用`UTF-8`这个神奇的咒语。

### gzip方法:将字符串变小的魔法

```java
    public static String gzip(String primStr) {
```
这是一个公共的静态方法,它接受一个字符串参数`primStr`,然后尝试将其变小。

```java
        if (primStr == null || primStr.length() == 0) {
            return primStr;
        }
```
在施展魔法前,我们先检查这个字符串是否为空或不存在,如果是,就直接返回原字符串。

```java
        ByteArrayOutputStream out = new ByteArrayOutputStream();
```
我们召唤了一个名为`ByteArrayOutputStream`的容器,用来暂时存放压缩后的数据。

```java
        String result = null;
        GZIPOutputStream gzip = null;
```
然后,我们准备了两个变量,一个用来存储结果,另一个将用于实际的压缩工作。

```java
        try {
            gzip = new GZIPOutputStream(out);
            gzip.write(primStr.getBytes(DEFAULT_ENCODING));
            gzip.finish();
```
在`try`块中,我们开始了真正的魔法:创建一个`GZIPOutputStream`对象,并用它来压缩字符串。`gzip.finish()`是告诉它,我们已经完成了压缩。

```java
            result = new String(new Base64().encode(out.toByteArray()), DEFAULT_ENCODING);
```
魔法完成后,我们将压缩后的数据编码成Base64格式,这样它们就可以被安全地存储和传输了。

```java
        } catch (IOException e) {
            log.error("ZipUtils.gzip.error", e);
            throw new RuntimeException(e);
        } finally {
```
如果在压缩过程中遇到任何错误,`log`助手会记录下来,并向外界抛出一个运行时异常。

```java
            if (gzip != null) {
                try {
                    gzip.close();
                } catch (IOException e) {
                    log.error("ZipUtils.gzip.close.error", e);
                }
            }
        }
```
最后,无论成功或失败,我们都确保关闭了压缩流,以释放资源。

```java
        return result;
    }
```
最终,我们返回压缩后的字符串。

### unGzip方法:恢复原状的魔法

接下来是`unGzip`方法,它和`gzip`方法相反,将压缩的字符串恢复原状。这个过程同样有趣,涉及到解码和解压的步骤,最终将压缩的数据恢复成原始字符串。

这个类就像一个魔法师,能够将数据在压缩和解压之间*转换,极大地提升了数据传输的效率。通过这样的技术,我们能够确保信息在网络中的快速流通,同时节省存储空间。这不仅是技术的展示,更是对效率和实用性的追求。