一、缘起

mysql在存储大文本时,有blob、text、mediumblob、mediumtext等字段类型可选。

最大值 对大小写是否敏感
blob 64k Y
text 64k N
mediumblob 16M Y
mediumtext 16M N

当下业务相对粗犷, 对html网页采用"先存储后使用", 原始数据留有备份, 方便多次使用。而网页是纯文本型, 类似博客评论,但实际大部分大小超过80KB,故先用gzip压缩算法处理网页, 然后存储压缩后的文本。(gzip在此场景下的压缩率接近70%, html压缩后大小普遍在10k之内)。现需要解码该文本, 还原原html并进行数据解析提取操作. 网上查阅知大部分python处理gzip字符串就是使用gzip的decompress、StringIO、zlib等等,但都不适用本场景. 下方给出python版处理,顺便贴出参考的java代码。

二、python代码

def my_ungzip(in_str):
    decode_str = base64.decodebytes(in_str)    # 先使用base64解码,不然会报header check等错误
    s = zlib.decompress(decode_str, 16 + zlib.MAX_WBITS).decode()
    print("gzip字符串解码后:\n", s)
    return s

代码运行结果如下:

python gzip字符串解码_html

三、参考的java版代码

本次参考的java,实测可行.

import org.apache.commons.lang.StringUtils;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.util.Base64;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;

/**
 * @author zmh
 * @date 2020-01-07
 * <p>
 * Gzip压缩字符串工具类
 */
class GzipUtils {

    public static final String GZIP_ENCODE_UTF_8 = "UTF-8";

    /**
     * base64 编码
     *
     * @param bytes 传入bytes
     * @return 编码成string类型的base64返回
     */
    public static String base64encode(byte[] bytes) {
        return new String(Base64.getEncoder().encode(bytes));
    }

    /**
     * base64 解码
     *
     * @param string 传入string类型的base64编码
     * @return 解码成byte类型返回
     */
    public static byte[] base64decode(String string) {
        return Base64.getDecoder().decode(string);
    }

    /**
     * 压缩字符串
     *
     * @param string 需要压缩的字符串
     * @return 压缩后内容 并转base64 返回
     */
    public static String gzip(String string) {
        String result = "";
        if (StringUtils.isBlank(string)) {
            return result;
        }
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        GZIPOutputStream gzip;
        try {
            gzip = new GZIPOutputStream(out);
            gzip.write(string.getBytes(GZIP_ENCODE_UTF_8));
            gzip.close();
            out.close();
            result = base64encode(out.toByteArray());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 解压缩字符串
     *
     * @param string base64格式的压缩后字符串
     * @return 解码并解压缩后返回
     */
    public static String unGzip(String string) {
        String result = "";
        if (StringUtils.isBlank(string)) {
            return result;
        }
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        ByteArrayInputStream in;
        GZIPInputStream ungzip;
        byte[] bytes = base64decode(string);
        try {
            in = new ByteArrayInputStream(bytes);
            ungzip = new GZIPInputStream(in);
            byte[] buffer = new byte[1024];
            int len = 0;
            while ((len = ungzip.read(buffer)) != -1) {
                out.write(buffer, 0, len);
            }
            ungzip.close();
            out.close();
            in.close();
            result = out.toString(GZIP_ENCODE_UTF_8);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    public static void main(String[] args) {
        long temp = System.currentTimeMillis();
        String test = "Gzip压压压压缩缩缩缩缩测试测试测试测试测试试试试试试试试试试试aaaabbbbbccccccaaaabbbbbccccccaaaabbbbbccccccdddddd111111111111111111111111111111111111111";
        String gzip = gzip(test);
        String unGzip = unGzip(gzip);
        System.out.println("原文:" + test);
        System.out.println("Gzip压缩:" + gzip);
        System.out.println("Gzip解压:" + unGzip);
        System.out.println("整体消耗时间: " + (System.currentTimeMillis() - temp) + " ms");
    }
}

如果更佳便捷的方式方法, 欢迎留言探讨,谢谢~!