Czy istnieją klasy Objective-C, które są równoważne klasom zawartym w pakiecie Java java.util.zip
?
Czy wykonanie polecenia CLI jest jedyną alternatywą?Tworzenie archiwum ZIP z aplikacji Cocoa
Odpowiedz
Od wersji iOS8/OSX10.10 istnieje wbudowany sposób tworzenia archiwów zip przy użyciu NSFileCoordinatorReadingOptions.ForUploading
. Prostym przykładem tworzyć archiwa ZIP bez żadnych zależności zakaz kakao:
public extension NSURL {
/// Creates a zip archive of the file/folder represented by this URL and returns a references to the zipped file
///
/// - parameter dest: the destination URL; if nil, the destination will be this URL with ".zip" appended
func zip(dest: NSURL? = nil) throws -> NSURL {
let destURL = dest ?? self.URLByAppendingPathExtension("zip")
let fm = NSFileManager.defaultManager()
var isDir: ObjCBool = false
let srcDir: NSURL
let srcDirIsTemporary: Bool
if let path = self.path where self.fileURL && fm.fileExistsAtPath(path, isDirectory: &isDir) && isDir.boolValue == true {
// this URL is a directory: just zip it in-place
srcDir = self
srcDirIsTemporary = false
} else {
// otherwise we need to copy the simple file to a temporary directory in order for
// NSFileCoordinatorReadingOptions.ForUploading to actually zip it up
srcDir = NSURL(fileURLWithPath: NSTemporaryDirectory()).URLByAppendingPathComponent(NSUUID().UUIDString)
try fm.createDirectoryAtURL(srcDir, withIntermediateDirectories: true, attributes: nil)
let tmpURL = srcDir.URLByAppendingPathComponent(self.lastPathComponent ?? "file")
try fm.copyItemAtURL(self, toURL: tmpURL)
srcDirIsTemporary = true
}
let coord = NSFileCoordinator()
var error: NSError?
// coordinateReadingItemAtURL is invoked synchronously, but the passed in zippedURL is only valid
// for the duration of the block, so it needs to be copied out
coord.coordinateReadingItemAtURL(srcDir, options: NSFileCoordinatorReadingOptions.ForUploading, error: &error) { (zippedURL: NSURL) -> Void in
do {
try fm.copyItemAtURL(zippedURL, toURL: destURL)
} catch let err {
error = err as NSError
}
}
if srcDirIsTemporary { try fm.removeItemAtURL(srcDir) }
if let error = error { throw error }
return destURL
}
}
public extension NSData {
/// Creates a zip archive of this data via a temporary file and returns the zipped contents
func zip() throws -> NSData {
let tmpURL = NSURL(fileURLWithPath: NSTemporaryDirectory()).URLByAppendingPathComponent(NSUUID().UUIDString)
try self.writeToURL(tmpURL, options: NSDataWritingOptions.DataWritingAtomic)
let zipURL = try tmpURL.zip()
let fm = NSFileManager.defaultManager()
let zippedData = try NSData(contentsOfURL: zipURL, options: NSDataReadingOptions())
try fm.removeItemAtURL(tmpURL) // clean up
try fm.removeItemAtURL(zipURL)
return zippedData
}
}
znajduje się zamek błyskawiczny ramowy http://code.google.com/p/zip-framework/, ale wydaje się, że w początkowej (wersja 0.1) stopnia.
Inne odpowiedzi na cocoadev: http://cocoadev.com/ZipArchiveLibraryForCocoa
Jedna odpowiedź stamtąd: ZipKit, https://github.com/kolpanic/ZipKit
ZipKit wydaje się lepiej wymienić swoje metody niż ZipArchive (nawet jeśli nie rozumiem, dlaczego to poprzedza jego metody dodatkowo). – kiamlaluno
Metody określania prefiksów lub sufiksów pomagają uniknąć kolizji nazw, jeśli Apple kiedykolwiek doda metodę w Cocoa pod tą samą nazwą. –
ZipKit jest teraz na https://github.com/kolpanic/ZipKit i nie jest już na bitbucket (shocker) – uchuugaka
odjazdu http://code.google.com/p/ziparchive/. Jest to klasa do kompresowania plików. Google to twój przyjaciel!
Oprócz czytania i zapisywania archiwów zip w swoim procesie, nie ma wstydu używać NSTask do uruchamiania zip
i unzip
.
Użycie tej metody pozwoliłoby na niezmienianie kodu w celu obsługi nowych funkcji. Zastanawiam się, co dokładnie robi Finder po wybraniu pliku/katalogu, a następnie wybierz "Kompresuj" z menu. Z jakiego pliku wykonywalnego korzysta Finder? – kiamlaluno
Używa narzędzia Archive Utility. –
Wyjazd zipzap, mój szybki plik zip I/O biblioteki.
To jest świetne, ale co z tym na odwrót? To znaczy, mając plik zip, a następnie czytając jego zawartość tak, jakby był katalogiem? – adib
Wyglądałem, ale nie mogłem znaleźć żadnej podobnej metody, aby przejść na drugą stronę. Głosowałem za tą odpowiedzią, ponieważ jest niesamowita. Jednak w mojej aplikacji na Macu użyłem NSTask do wywołania/usr/bin/zip i/usr/bin/unzip. Jest to proste, oferuje wiele * udokumentowanych * opcji kontrolowania zachowania, aw moim przypadku miało mniej kodu niż ten. –