在 Swift 中从字符串创建 ZIP 文件

use*_*025 6 zip nsfilemanager ios swift ssziparchive

 let data = "InPractiseThisWillBeAReheallyLongString"
     
        createDir()
        
        let docsDir = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
        let ourDir = docsDir.appendingPathComponent("ourCustomDir/")
        let tempDir = ourDir.appendingPathComponent("temp/")
        let unzippedDir = tempDir.appendingPathComponent("unzippedDir/")
        let unzippedfileDir = unzippedDir.appendingPathComponent("unZipped.txt")
        let zippedDir = tempDir.appendingPathComponent("Zipped.zip")
        do {
            
            try data.write(to: unzippedfileDir, atomically: false, encoding: .utf8)
            
            
            let x = SSZipArchive.createZipFile(atPath: zippedDir.path, withContentsOfDirectory: unzippedfileDir.path)
            
            var zipData: NSData! = NSData()
            
            do {
                zipData = try NSData(contentsOfFile: unzippedfileDir.path, options: NSData.ReadingOptions.mappedIfSafe)
                //once I get a readable .zip file, I will be using this zipData in a multipart webservice
            }
            catch let err as NSError {
                print("err 1 here is :\(err.localizedDescription)")
            }
        }
        catch let err as NSError {
            
            print("err 3 here is :\(err.localizedDescription)")
        }
Run Code Online (Sandbox Code Playgroud)

createDir函数为:

func createDir() {
        let docsDir = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
        let ourDir = docsDir.appendingPathComponent("ourCustomDir/")
        let tempDir = ourDir.appendingPathComponent("temp/")
        let unzippedDir = tempDir.appendingPathComponent("unzippedDir/")
        let fileManager = FileManager.default
        if fileManager.fileExists(atPath: tempDir.path) {
            deleteFile(path: tempDir)
            deleteFile(path: unzippedDir)
        } else {
            print("file does not exist")
            do {
                try FileManager.default.createDirectory(atPath: tempDir.path, withIntermediateDirectories: true, attributes: nil)
                try FileManager.default.createDirectory(atPath: unzippedDir.path, withIntermediateDirectories: true, attributes: nil)
                print("creating dir \(tempDir)")
            } catch let error as NSError {
                print("here : " + error.localizedDescription)
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

现在我没有收到任何错误,但是当我下载我的 appData 容器,获取 ZIP 文件并尝试解压缩时,我告诉 ZIP 文件是空的。我可以看到unzipped.text文件确实按预期存在。

知道我做错了什么吗?

有没有一种方法可以.zip直接从字符串创建 a而不必将文件保存到数据容器?


更新

我还尝试了以下方法并得到了完全相同的结果:

let zipArch = SSZipArchive(path: zippedDir.path)
        print(zipArch.open)
        print(zipArch.write(dataStr.data(using: String.Encoding.utf8)!, filename: "blah.txt", withPassword: ""))
        print(zipArch.close)
Run Code Online (Sandbox Code Playgroud)

Tho*_*ing 1

您可以使用ZIPFoundation,它是另一个 Swift ZIP 库,允许您读取、创建和修改 ZIP 文件。它的优点之一是它允许您“即时”添加 ZIP 条目。在从字符串创建存档之前,您不必将字符串写入磁盘。它提供了一个基于闭包的 API,您可以将字符串直接输入到新创建的存档中:

func zipString() {
    let string = "InPractiseThisWillBeAReheallyLongString"
    var archiveURL = URL(fileURLWithPath: NSTemporaryDirectory())
    archiveURL.appendPathComponent(ProcessInfo.processInfo.globallyUniqueString)
    archiveURL.appendPathExtension("zip")
    guard let data = string.data(using: .utf8) else { return }
    guard let archive = Archive(url: archiveURL, accessMode: .create) else { return }

    try? archive.addEntry(with: "unZipped.txt", type: .file, uncompressedSize: UInt32(data.count), provider: { (position, size) -> Data in
        return data
    })
}
Run Code Online (Sandbox Code Playgroud)

addEntry方法还有一个可选bufferSize参数,可用于执行分块加法(这样您就不必将整个数据对象加载到 RAM 中。)