我有一个函数应该创建一批文件,将它们写入目录,压缩该目录,然后将其附加到电子邮件中。
当我运行它时,它告诉我它已写入299个文件,但是当我打开zip文件夹时,正好丢失了50个文件
这是代码。我想把它修剪下去,但我害怕删除可能有助于某人发现问题的东西:
func exportAllData() {
var totalExports = 0
// fetch all the data first
// 1 Describe what you want
let fetchRequest = NSFetchRequest(entityName: "Fish")
let sortDescriptor = NSSortDescriptor(key: "time", ascending: false)
fetchRequest.sortDescriptors = [sortDescriptor]
// 2 Get it!
do {
let allCatches = try managedContext!.executeFetchRequest(fetchRequest) as? [NSManagedObject]
totalExports = allCatches!.count
// Create a folder to store the catches in
// path to where data will be written
let urls = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)
let applicationDocumentsDirectory:NSURL = urls[urls.count-1]
let destinationURL = applicationDocumentsDirectory.URLByAppendingPathComponent("filesToExport", isDirectory: true)
do { try NSFileManager.defaultManager().createDirectoryAtURL(destinationURL, withIntermediateDirectories: false, attributes: nil)
print("created directory")
var currentFile = 0
// Write each fish to file
for fish in allCatches! {
currentFile+= 1
// convert NSManagedObject into a Dictionary, serialize it to NSData, and write it to file
let keys = fish.entity.propertiesByName.keys.array
let dictionary = fish.dictionaryWithValuesForKeys(keys)
let data = NSKeyedArchiver.archivedDataWithRootObject(dictionary)
let fileName = "catchNumber\(currentFile)"
let fileURL = destinationURL.URLByAppendingPathComponent(fileName)
let success = data.writeToFile(fileURL.path!, atomically: false)
if success { print("successfully exported: "+fileName) } else { print("FAILED to export: "+fileName) }
}
// DEBUG
do {
let contents = try NSFileManager.defaultManager().contentsOfDirectoryAtPath(destinationURL.path!)
print(contents)
} catch {
print(error)
}
// After all the fish have been written to file, zip the file
let zipURL = applicationDocumentsDirectory.URLByAppendingPathComponent("exported.zip")
Main.createZipFileAtPath(zipURL.path!, withContentsOfDirectory: destinationURL.path!)
// Load the zip file up as data and send it out in an email
let zipData = NSData(contentsOfURL: zipURL)
let picker = MFMailComposeViewController()
picker.mailComposeDelegate = self
picker.setSubject("Shared Catch Log! (\(totalExports) entries)")
picker.setMessageBody("Open the attachment to this email on an iOS device with Catch Stats installed on it to import all catch into your Catch Log!", isHTML: false)
picker.addAttachmentData(zipData!, mimeType: "applcation/CatchStats", fileName: "CatchStatsLog.csl")
presentViewController(picker, animated: true, completion: nil)
// If failed to created directory
} catch {
print("directory already existed")
}
// If failed to execute fetch request
} catch {
print(error)
self.navigationController?.popViewControllerAnimated(true)
}
}
现在,在//Debug
,当我检查我即将压缩的文件夹的内容时,它有299个文件,编号从1到299。
但是当我通过电子邮件发送文件并将其打开时,50-99都丢失了。有人可以给我一些建议吗?
我从ZipArchive的Main.m文件中提取了这段代码。这就是它正在做的事情。
+ (BOOL)createZipFileAtPath:(NSString *)path
withContentsOfDirectory:(NSString *)directoryPath {
return [self createZipFileAtPath:path withContentsOfDirectory:directoryPath keepParentDirectory:NO];
}
+ (BOOL)createZipFileAtPath:(NSString *)path
withContentsOfDirectory:(NSString *)directoryPath
keepParentDirectory:(BOOL)keepParentDirectory {
BOOL success = NO;
NSFileManager *fileManager = nil;
Main *zipArchive = [[Main alloc] initWithPath:path];
if ([zipArchive open]) {
// Use a local file manager (queue/thread compatibility)
fileManager = [[NSFileManager alloc] init];
NSDirectoryEnumerator *directoryEnumerator = [fileManager enumeratorAtPath:directoryPath];
NSString *fileName;
while ((fileName = [directoryEnumerator nextObject])) {
BOOL isDirectory;
NSString *fullFilePath = [directoryPath stringByAppendingPathComponent:fileName];
[fileManager fileExistsAtPath:fullFilePath isDirectory:&isDirectory];
if (!isDirectory) {
if (keepParentDirectory) {
fileName = [[directoryPath lastPathComponent] stringByAppendingPathComponent:fileName];
}
[zipArchive writeFileAtPath:fullFilePath withFileName:fileName];
} else {
if (0 == [[NSFileManager defaultManager] subpathsOfDirectoryAtPath:fullFilePath error:nil].count) {
NSString *temporaryName = [fullFilePath stringByAppendingPathComponent:@".DS_Store"];
[@"" writeToFile:temporaryName atomically:YES encoding:NSUTF8StringEncoding error:nil];
[zipArchive writeFileAtPath:temporaryName withFileName:[fileName stringByAppendingPathComponent:@".DS_Store"]];
[[NSFileManager defaultManager] removeItemAtPath:temporaryName error:nil];
}
}
}
success = [zipArchive close];
}
return success;
}
答案 0 :(得分:0)
我找到了一个解决方案,但它更像是一种解决方案。经过大量测试后,我意识到ZipArchive无法压缩包含250个以上文件的文件夹。文件的名称或命令无关紧要。
我没有序列化每个NSDictionary并将其写入文件,而是创建了一个NSDictionaries数组,并将其序列化。这样ZipArchive只需要压缩一个文件,现在看起来工作正常。