爱智EdgerOS之深入解析文件和数据压缩模块ZIP与Zlib

一、“数据压缩“简介

  • 数据压缩是采用某种压缩算法减少文件大小的一个过程,这个过程可能包括对源文件的编码、重组和修改等操作,该过程的主要目标是在减少文件大小的同时,确保源文件中的数据不会丢失。文件经过压缩后,应可以使用相关的解码算法生成原始文件。

在这里插入图片描述

  • 对数据进行压缩的算法有很多种类,可以根据压缩后数据的完整性把压缩算法分为两大类:无损压缩和有损压缩。
  • 无损压缩是通过删除数据中的冗余来减少原始文件大小的数据压缩方法,因此文件的实际信息不会发生改变。有损压缩是通过删除数据中的一些不相关信息来减少原始文件大小的数据压缩方法,在某些不需要完整数据文件时可以使用这种类型的压缩。相比较于无损压缩,有损压缩的文件会小很多,但是无损压缩的优点在于能够确保数据完整的同时减少文件的大小。

二、ZIP

  • ZIP 是最常使用的文件压缩格式,它属于无损压缩方法。它的优点在于可以把多个源文件压缩在一起生成单个压缩文件。在 EdgerOS 中,ZIP 模块提供了 API 以支持对文件的压缩、解压缩、修改和遍历等功能。
  • 使用示例:
const Zip = require('zip')

// 解压文件 b.zip 到当前目录下的 b 文件夹中
Zip.extract('b.zip', './b')

// 压缩当前目录下的文件夹 c 将结果另存为 c.zip
Zip.compress('c.zip', './c')

// 遍历和读取压缩文件
const rzip = new Zip('a.zip', 'r') // a.zip 需已存在
const fileCnt = rzip.count() // 压缩文件中源文件的总数量
for (let i = 0; i < fileCnt; i++) {
    
    
    rzip.open(i); // 打开索引为 i 的文件
    
    const fileBuff = rzip.read() // 当前文件的内容
    
    const file = rzip.stat() // 获取当前文件的状态
    // file.name 文件名
    // file.index 当前文件在压缩文件中的索引
    // file.size 当前文件的大小
    // file.mode 当前文件的权限
    
    rzip.fread('indexi.out') // 解压当前文件到 indexi.out 文件中
    
    rzip.close() // 关闭当前文件
}
rzip.end()


// 修改和生成新的压缩文件
const wzip = new Zip('b.zip', 'w'); // b.zip 可以不存在
wzip.open('bb.txt') // 
wzip.write('append content or new content string') // 向当前打开的压缩文件中写入一段内容
wzip.close()

wzip.open('cc.txt')
wzip.fwrite('./cc.txt') // 把当前目录下的 cc.txt 压缩后添加到压缩文件中 
wzip.close()

wzip.end()

三、Zlip

  • Zlib 是一个应用广泛的无损压缩库,EdgerOS 中的 Zlib 模块在提供对内存中数据压缩和解压方法的同时,还提供了对 Gzip 文件和数据处理的 API。

① 利用 Zlib 解压和压缩

const zlib = require('zlib')

// 压缩字符串并保存到 buffer 中,指定压缩级别为 9
const data = 'string to compress'
const compBuffer = zlib.compress(data, 9)

// 从压缩后的 buffer 中提取原字符串
const decompBuffer = zlib.decompress(data.length, compBuffer)
console.log(decompBuffer.toString()) // => 'string to compress'

③ 利用 Gzip 解压和压缩

  • Gzip 也是一种无损的压缩方法,它主要用于压缩单个文件,当有一个很大的文件时,Gzip 比其他方法的性能更好。如果需要压缩多个文件时,则需要配合 Tar 一起使用,即先使用 Tar 把多个文件归档为一个文件,再把这个归档文件用 Gzip 进行压缩。
const {
    
     gz } = require('zlib')

// 读取一个已存在的 gzip 文件
const gzfile = gz.open('input.gz', 'r')
const buffer = new Buffer(1024) // 读取的临时缓冲 Buffer

while (true) {
    
    
    const num = gzfile.read(buffer)  // 解压 gzip 文件并读取
    if (num > 0) {
    
    
        const content = buffer.slice(0, num) // 已读取成功的 Buffer
        console.log(content.toString('hex'))
    } else {
    
    
        break
    }
}

gzfile.close()

const gzwfile = gz.open('output.gz', 'w')
gzfile.write('hello gzip file!') // 将当前字符串压缩并写入 ouput.gz 中
gzfile.close()
  • Zlib 提供 API 支持以文件流的方式读取和写入 Gzip 文件:

const {
    
     gz } = require('zlib')
const fs = require('fs')

// 以流的方式解压并写入到新文件
const rs = gz.createReadStream('input.tar.gz') // 创建一个 gzip 的可读流
const ws = fs.createWriteStream('input.tar') // 创建一个文件写入流,用于将解压后的数据写入到当前文件
rs.pipe(ws) // 支持 pipe 方法直接将 gzip 的可读流写入到标准文件的可写流中
ws.on('finish', () => console.log('decompressed!'))

// 以流的方式压缩并写入到新文件
const r = fs.createReadStream('input.tar') // 根据待压缩的文件创建一个可读流
const w = gz.createWriteStream('input.tar.gz') // 创建一个 gzip 的可写流
r.pipe(w) // 在 pipe 的同时会将原数据进行压缩
w.on('finish', () => console.log('compressed!'))

猜你喜欢

转载自blog.csdn.net/Forever_wj/article/details/129628194