iOS将压缩的NSData写入文件会生成损坏的zip文件

问题描述 投票:1回答:1

我正在尝试在我的iOS应用程序中实现一个非常简单的功能:将文件压缩到Documents文件夹中。我写了以下FileManager扩展名:

extension FileManager {


    func zipFile(url: URL, deleteOriginal: Bool = false) {
        guard let fileData = try? Data(contentsOf: url) else { return }
        let nsdata = fileData as NSData
        let zipped: NSData
        zipped = (try? nsdata.compressed(using: .zlib)) ?? nsdata
        let zip = zipped as Data
        let zipUrl = url.deletingPathExtension().appendingPathExtension("zip")
        try? FileManager.default.removeItem(at: zipUrl)
        try? zip.write(to: zipUrl)
        if deleteOriginal {
            try? FileManager.default.removeItem(at: url)
        }
    }

}

但是,创建的文件似乎已损坏。

我进入Xcode-> Window-> 设备和模拟器,选择我的设备,然后在其下面的列表中选择我的应用程序,单击列表下的齿轮按钮,然后单击在下载容器...上查看文件。然后,我打开下载的软件包的内容并检查Documents文件夹-文件夹中有创建的zip文件。但是,我无法打开它。默认情况下,Mac创建的文件扩展名为zip.cpgz,通常在文件损坏时会这样做。其他提取器应用程序显示一条错误消息,告知文件已损坏。当我尝试使用unzip在终端中打开它时,看到以下消息:

iMac:Downloads user$ unzip myzip.zip
Archive:  myzip.zip
  End-of-central-directory signature not found.  Either this file is not
  a zipfile, or it constitutes one disk of a multi-part archive.  In the
  latter case the central directory and zipfile comment will be found on
  the last disk(s) of this archive.
unzip:  cannot find zipfile directory in one of myzip.zip or
        myzip.zip.zip, and cannot find myzip.zip.ZIP, period.

我不仅尝试了NSData.compressed,还尝试了一个名为DataCompression的库,还使用here中的Apple指令实现了“我自己”的压缩。在所有情况下,文件都以相同的方式损坏。

我还尝试调试代码,在调试器中显示压缩的Data对象,并将其导出为文件。再次以相同的症状损坏。

我做错什么了吗?请让我知道如何将内容压缩并保存到文件,而不仅仅是[NS] Data,就像在StackOverflow中的大多数答案中一样。

ios swift zip compression nsdata
1个回答
0
投票

ZIP是一种存档文件格式,它还支持压缩(但它也可以包含未压缩的文件)。

ZIP归档文件不仅仅包含压缩文件的内容。它还维护所有文件,目录和符号链接的索引。该索引称为中央目录,并附加到文件末尾。此外,存档中的每个文件还附带了一些元数据。此本地文件头包含诸如文件创建日期,文件属性,文件路径等信息。您可以找到ZIP格式here的完整规范。

我发布了一个可用于在Swift中处理ZIP存档的小型框架:https://github.com/weichsel/ZIPFoundation

使用此框架,您可以使用以下代码从单个文件创建档案:

let fileManager = FileManager()
let currentWorkingPath = fileManager.currentDirectoryPath
var sourceURL = URL(fileURLWithPath: currentWorkingPath)
sourceURL.appendPathComponent("file.txt")
var destinationURL = URL(fileURLWithPath: currentWorkingPath)
destinationURL.appendPathComponent("archive.zip")
do {
    try fileManager.zipItem(at: sourceURL, to: destinationURL)
} catch {
    print("Creation of ZIP archive failed with error:\(error)")
}
© www.soinside.com 2019 - 2024. All rights reserved.