DataCompression (数据压缩)

用于 Data 类型的 libcompression 封装扩展

支持的压缩算法包括

系统要求

Swift 版本支持

库版本 Swift 版本
3.8.0 5.7 (Xcode 14)
3.6.0 5.1 (Xcode 11)
3.5.0 5.0
3.1.0 4.2
3.0.0 3.0 -> 4.1
2.0.1 < 3.0

使用示例

尝试所有算法并比较压缩率

let raw: Data! = String(repeating: "There is no place like 127.0.0.1", count: 25).data(using: .utf8)

print("raw   =>   \(raw.count) bytes")

for algo: Data.CompressionAlgorithm in [.zlib, .lzfse, .lz4, .lzma] {
    let compressedData: Data! = raw.compress(withAlgorithm: algo)

    let ratio = Double(raw.count) / Double(compressedData.count)
    print("\(algo)   =>   \(compressedData.count) bytes, ratio: \(ratio)")
    
    assert(compressedData.decompress(withAlgorithm: algo)! == raw)
}

将会打印如下内容

raw    =>   800 bytes
zlib   =>    40 bytes, ratio:  20.00
lzfse  =>    69 bytes, ratio:  11.59
lz4    =>   181 bytes, ratio:   4.42
lzma   =>   100 bytes, ratio:   8.00

容器格式

著名的 zlib deflate 算法 (RFC-1951) 也可以通过快捷方式 .deflate().inflate() 使用
let data: Data! = "https://www.ietf.org/rfc/rfc1951.txt".data(using: .utf8)
let deflated: Data! = data.deflate()
let inflated: Data? = deflated?.inflate()
assert(data == inflated)
gzip 格式的数据 (RFC-1952) 可以通过 .gzip().gunzip() 处理
let data: Data! = "https://www.ietf.org/rfc/rfc1952.txt".data(using: .utf8)
let gzipped: Data! = data.gzip()
let gunzipped: Data? = gzipped.gunzip()
assert(data == gunzipped)

注意:gzip 格式的压缩数据总是比原始 deflate 数据大 18 个字节,并且会附加/执行基于 crc32 校验和的数据完整性测试。

zip 格式的数据 (RFC-1950) 可以通过 .zip().unzip() 处理
let data: Data! = "https://www.ietf.org/rfc/rfc1950.txt".data(using: .utf8)
let zipped: Data! = data.zip()
let unzipped: Data? = zipped.unzip()
assert(data == unzipped)

注意:zip 格式的压缩数据总是比原始 deflate 数据大 6 个字节,并且会附加/执行基于 adler32 校验和的数据完整性测试。

在命令行压缩文件并在 Swift 中解压缩

最简单的方法是使用已经安装的 gzip 命令行工具。假设你有一个名为 file.txt 的文件,在调用

gzip -9 file.txt

文件应该已经被压缩为 file.txt.gz。现在你可以加载并解压缩你的文件内容,使用

let compressedData = try? Data(contentsOf: URL(fileURLWithPath: "/path/to/your/file.txt.gz"))

if let uncompressedData = compressedData?.gunzip() {
    print(String(data: uncompressedData, encoding: .utf8) ?? "Can't decode UTF-8")
}

校验和扩展

虽然与压缩无关,但为了方便,Crc32Adler32 方法也暴露在 Data 类型上,这可能会很方便。

let classicExample = "The quick brown fox jumps over the lazy dog".data(using: .utf8)!
let crc32    = classicExample.crc32()
let adler32  = classicExample.adler32()
print("crc32: \(crc32), adler32: \(adler32)")

将会打印

crc32: 414fa339, adler32: 5bdc0fda

安装

Cocoa Pods

要使用 CocoaPods 将 DataCompression 集成到你的 Xcode 项目中,请将其添加到你的 Podfile

target '<your_target_name>' do
    pod 'DataCompression'
end

然后,运行以下命令

$ pod install

然后你需要在你的 swift 源文件顶部添加 import DataCompression 以使用该扩展。

Carthage

注意: DataCompression 版本 < 3.3.0 与 Carthage 不兼容。这意味着仅支持 Swift 5。

要使用 Carthage 将 DataCompression 集成到你的 Xcode 项目中,请将其作为依赖项添加到你的 Cartfile。只需添加

github "mw99/DataCompression"

然后你必须在你的 Xcode 项目的 carthage copy-frameworks 运行脚本阶段中添加框架路径。路径可能因你设置项目与 Carthage 的关系而异。

输入
$(SRCROOT)/Carthage/Build/iOS/DataCompression.framework
输出
$(BUILT_PRODUCTS_DIR)/$(FRAMEWORKS_FOLDER_PATH)/DataCompression.framework

然后你需要在你的 swift 源文件顶部添加 import DataCompression 以使用该扩展。

Swift Package Manager

要使用 Swift Package Manager 将 DataCompression 集成到你的 Xcode 项目中,请将其作为依赖项添加到你的 Package.swift 文件

import PackageDescription

let package = Package(
    name: "<your_package_name>",
    dependencies: [
        .Package(url: "https://github.com/mw99/DataCompression.git", majorVersion: 3)
    ]
)

然后你需要在你的 swift 源文件顶部添加 import DataCompression 以使用该扩展。

下次你运行 swift build 时,新的依赖项将被解析。

$ swift build

或者直接将文件复制到你的项目中

你只需要一个位于 Sources/DataCompression.swift 的文件。将其拖放到 Xcode 项目导航器中。

更新日志 / 升级指南

版本 3.7.03.8.0
版本 3.6.03.7.0
版本 3.5.03.6.0
版本 3.4.03.5.0
版本 3.3.03.4.0
版本 3.2.03.3.0
版本 3.1.03.2.0
版本 3.0.03.1.0
版本 2.0.X3.0.0

许可证

Apache 许可证,版本 2.0
版权所有 2016, Markus Wanke

根据 Apache 许可证 2.0 版(“许可证”)获得许可;除非遵守许可证,否则您不得使用此文件。您可以在以下网址获取许可证副本:

https://apache.ac.cn/licenses/LICENSE-2.0

除非适用法律要求或书面同意,否则根据许可证分发的软件按“现状”分发,不附带任何明示或暗示的保证或条件。请参阅许可证以了解有关权限和限制的特定语言。