在 Swift (iOS/macOS) 中处理 ZIP/归档文件:完整指南

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

在 Swift (iOS/macOS) 中处理 ZIP/归档文件

在现代 iOS 和 macOS 开发中,经常需要打包和解包文件。ZIP 归档是一种标准的数据压缩方式,在所有 Apple 平台上都受支持。在本文中,我们将探讨 Swift 中用于处理 ZIP 的原生工具,以及流行的 ZIPFoundation 库。



Foundation 原生工具

Foundation 框架通过 NSFileCoordinator 类和系统工具提供了基本的归档处理能力。然而,要全面处理 ZIP,建议使用第三方库或系统命令的封装。



ZIPFoundation 库

ZIPFoundation 是一个轻量级的 ZIP 归档处理库,使用纯 Swift 编写。它支持 iOS、macOS、tvOS 和 watchOS,无需外部依赖,并在 MIT 许可下发布。



通过 Swift Package Manager 安装

在 Package.swift 中添加依赖:

dependencies: [    .package(url: "https://github.com/weichsel/ZIPFoundation.git", from: "0.9.16")]

或者通过 Xcode:File → Add Packages → 输入仓库 URL。



基本操作



1. 创建 ZIP 归档

打包单个文件:

import ZIPFoundation

let fileManager = FileManager.defaultlet sourceURL = URL(fileURLWithPath: "/path/to/file.txt")let destinationURL = URL(fileURLWithPath: "/path/to/archive.zip")

do { try fileManager.zipItem(at: sourceURL, to: destinationURL) print("归档已创建: \\(destinationURL.path)")} catch { print("错误: \\(error.localizedDescription)")}


打包整个目录:

let directoryURL = URL(fileURLWithPath: "/path/to/folder")let archiveURL = URL(fileURLWithPath: "/path/to/folder.zip")

do { try fileManager.zipItem(at: directoryURL, to: archiveURL) print("目录已打包")} catch { print("错误: \\(error)")}


2. 解压归档

let archiveURL = URL(fileURLWithPath: "/path/to/archive.zip")let destinationURL = URL(fileURLWithPath: "/path/to/unzip")

do { try fileManager.unzipItem(at: archiveURL, to: destinationURL) print("解压完成")} catch { print("解压错误: \\(error)")}


3. 在不提取的情况下处理归档内容

guard let archive = Archive(url: archiveURL, accessMode: .read) else {    fatalError("无法打开归档")}

// 列出所有条目for entry in archive { print("文件: \\(entry.path), 大小: \\(entry.uncompressedSize) 字节")}

// 读取特定文件if let entry = archive["documents/report.pdf"] { var data = Data() do { _ = try archive.extract(entry, bufferSize: 4096) { partialData in data.append(partialData) } print("已提取 \\(data.count) 字节") } catch { print("错误: \\(error)") }}


4. 向现有归档添加文件

guard let archive = Archive(url: archiveURL, accessMode: .update) else {    fatalError("无法打开归档进行更新")}

let newFileURL = URL(fileURLWithPath: "/path/to/new_file.txt")do { try archive.addEntry(with: "new_file.txt", relativeTo: newFileURL.deletingLastPathComponent()) print("文件已添加")} catch { print("错误: \\(error)")}


处理进度和大文件

对于大型归档,请使用 Progress:

let progress = Progress(totalUnitCount: 100)let archiveURL = URL(fileURLWithPath: "/path/to/large.zip")let destinationURL = URL(fileURLWithPath: "/path/to/output")

do { try FileManager.default.unzipItem(at: archiveURL, to: destinationURL, progress

推荐