7
 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)")
        }

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)
            }
        }
    }

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

知道我做错了什么吗?

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


更新

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

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)
4

3 回答 3

3

我用 ZipFoundation 做到了——> https://github.com/weichsel/ZIPFoundation

迅速

100% 工作!!

1) 将 ZipFoundation 框架添加到您的项目中

2)将导入添加到您的班级

   import ZIPFoundation //Add to top of your class

调用函数

     zipString() . // Do your work
     extract(fileName: "myZip.zip") //Extract it to test it
     read(fileName : "zipTxt.txt" )  //Read you extracted File

为您的班级添加功能

func zipString() {

    let zipName = "myZip.zip"
    let myTxtName = "zipTxt.txt"
    let myString = "I love to zip files"  // In your case "InPractiseThisWillBeAReheallyLongString"

    if let dir = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first {
        let fileURL = dir.appendingPathComponent(zipName)

        //Create the zip file
        guard let archive = Archive(url: fileURL, accessMode: .create) else  {
            return
        }

       /* guard let archive = Archive(url: fileURL, accessMode: .update) else  {
            return
        } */ // In case you want to update

        print("CREATED")

         //Add file to
        let data = myString.data(using: .utf8)
        try? archive.addEntry(with: myTxtName, type: .file, uncompressedSize: UInt32(data!.count), compressionMethod: .deflate, provider: { (position, size) -> Data in

            return data!
        })

         print("ADDED")
    }

}

奖金文件提取

    /**
 ** Extract file for a given name
 **/
func extract(fileName : String){

    let fileManager = FileManager()
    let file = fileName
    // let currentWorkingPath = fileManager.currentDirectoryPath
    if let dir = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first {

        let fileURL = dir.appendingPathComponent(file)
        do {
            // try fileManager.createDirectory(at: dir, withIntermediateDirectories: true, attributes: nil)
            try fileManager.unzipItem(at: fileURL, to: dir)
            print("EXTRACTED")

        } catch {
            print("Extraction of ZIP archive failed with error:\(error)")
        }

    }

}

用于测试您提取的文件

      func read(fileName : String){
    let file = fileName //this is the file. we will write to and read from it

    if let dir = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first {

        let fileURL = dir.appendingPathComponent(file)

        //reading
        do {
            let text2 = try String(contentsOf: fileURL, encoding: .utf8)
            print(text2)
        }
        catch {/* error handling here */}
    }
}

我的控制台输出...

已创建

添加

提取的

我喜欢压缩文件

于 2018-08-14T20:41:32.610 回答
3

您可以使用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
    })
}

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

于 2017-10-20T14:47:08.577 回答
1

小提示:您可以在不使用第三方库的情况下压缩任何内容;)

/// Zip the itemAtURL (file or folder) into the destinationFolderURL with the given zipName
/// - Parameters:
///   - itemURL: File or folder to zip
///   - destinationFolderURL: destination folder
///   - zipName: zip file name
/// - Throws: Error in case of failure in generating or moving the zip
func zip(itemAtURL itemURL: URL, in destinationFolderURL: URL, zipName: String) throws {
    var error: NSError?
    var internalError: NSError?
    NSFileCoordinator().coordinate(readingItemAt: itemURL, options: [.forUploading], error: &error) { (zipUrl) in
        // zipUrl points to the zip file created by the coordinator
        // zipUrl is valid only until the end of this block, so we move the file to a temporary folder
        let finalUrl = destinationFolderURL.appendingPathComponent(zipName)
        do {
            try FileManager.default.moveItem(at: zipUrl, to: finalUrl)
        } catch let localError {
            internalError = localError as NSError
        }
    }
    
    if let error = error {
        throw error
    }
    if let internalError = internalError {
        throw internalError
    }
}
于 2021-09-17T11:44:12.023 回答