首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >从Swift中的字符串创建ZIP文件

从Swift中的字符串创建ZIP文件
EN

Stack Overflow用户
提问于 2017-10-18 15:40:49
回答 3查看 9.5K关注 0票数 8
代码语言:javascript
运行
复制
 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函数是:

代码语言:javascript
运行
复制
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,而不必将文件保存到数据容器中?

更新

我还尝试了以下几点,并得到了完全相同的结果:

代码语言:javascript
运行
复制
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)
EN

回答 3

Stack Overflow用户

发布于 2018-08-14 20:41:32

我是用ZipFoundation -> https://github.com/weichsel/ZIPFoundation做的

斯威夫特

100%工作!

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

2)将导入添加到类中

代码语言:javascript
运行
复制
   import ZIPFoundation //Add to top of your class

呼叫功能

代码语言:javascript
运行
复制
     zipString() . // Do your work
     extract(fileName: "myZip.zip") //Extract it to test it
     read(fileName : "zipTxt.txt" )  //Read you extracted File

将函数添加到类中

代码语言:javascript
运行
复制
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")
    }

}

奖金文件提取

代码语言:javascript
运行
复制
    /**
 ** 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)")
        }

    }

}

用于测试提取的文件

代码语言:javascript
运行
复制
      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 */}
    }
}

我的控制台输出..。

已创建

已添加

提取

我喜欢压缩文件

票数 2
EN

Stack Overflow用户

发布于 2021-09-17 11:44:12

注意:不需要使用第三方库就可以压缩任何东西;)

代码语言:javascript
运行
复制
/// 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
    }
}
票数 2
EN

Stack Overflow用户

发布于 2017-10-20 14:47:08

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

代码语言:javascript
运行
复制
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参数,可以用来执行块加(这样就不必将整个数据对象加载到内存中)。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46814128

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档