[英]Empty files in app documents directory
我的应用程序有一个草稿表视图,其中显示了用户保存的音频文件。 对于数据源数组,我遍历了drafts目录(在NSDocumentDirectory
内部)。 该代码工作正常,并且显示了到目前为止我保存的所有文件。
问题是,就在最近,除了前两个文件以外,所有文件都是空的。 空的意思是:当我使用NSData的datatWithContentsOfFile
方法时,数据长度为0,即0个字节。 前两个文件仍具有数据,每个文件约267639 b。
但是,如果文件中没有数据,当我在草稿目录中循环浏览时,为什么会出现这些数据? 这些空文件直到最近才完好无损。 是什么原因导致它们变空了?
以下是用于遍历草稿目录的代码。
// check if drafts folders exist
BOOL draftsFoldersExist = NO;
NSError *error = nil;
NSArray *folders = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSArray *appFolderContents = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:[folders objectAtIndex:0] error:&error];
if ([appFolderContents count] > 0 && error == nil) {
for (NSString *item in appFolderContents) {
if ([item isEqualToString:@"drafts"])
draftsFoldersExist = YES;
}
}
_draftsArray = [[NSMutableArray alloc] init];
if (draftsFoldersExist) {
// drafts data source
NSString *draftsPath = [NSString stringWithFormat:@"%@/drafts", [folders objectAtIndex:0]];
NSString *draftsPathEncoded = [draftsPath stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSURL *draftsPathURL = [NSURL URLWithString:draftsPathEncoded];
// enumerate files in drafts folders
NSArray *desiredProperties = @[NSURLIsReadableKey, NSURLCreationDateKey];
NSArray *drafts = [[NSFileManager defaultManager] contentsOfDirectoryAtURL:draftsPathURL includingPropertiesForKeys:desiredProperties options:0 error:&error];
for (NSURL *item in drafts) {
NSMutableDictionary *draftDict = [[NSMutableDictionary alloc] init];
// name
NSString *name = [item lastPathComponent];
// is readable
NSNumber *isReadableBoolValue = nil;
[item getResourceValue:&isReadableBoolValue forKey:NSURLIsReadableKey error:&error];
if ([isReadableBoolValue isEqualToNumber:@YES]) {
// filename
[draftDict setValue:[name stringByDeletingPathExtension] forKey:@"draftFilename"];
// creation date
NSDate *creationDate = nil;
[item getResourceValue:&creationDate forKey:NSURLCreationDateKey error:&error];
[draftDict setValue:creationDate forKey:@"creationDate"];
// insert into first position of data source array
_draftsArray = [[@[draftDict] arrayByAddingObjectsFromArray:_draftsArray] mutableCopy];
// meta
} else {
NSLog(@"unreadable item: %@", name);
}
}
}
更新:
我按照@Joride的建议通过管理器下载了应用程序目录的文件,发现所有文件完整无缺,并带有数据。 他们来了:
2014-08-08_20-53-30.m4a
2014-08-09_19-11-08.m4a
2014-08-10_17-36-28.m4a
2014-08-11_18-53-46.m4a
2014-08-13_12-57-57.m4a
2014-08-16_20-44-33.m4a
2014-08-16_20-45-06.m4a
我想现在的问题是,为什么其中一些不使用dataWithContentsOfFile
方法显示任何数据。
我使用以下代码初始化NSData对象:
NSData *fileData = [NSData dataWithContentsOfFile:filepath options:NSDataReadingMapped error:&readingError];
对于数据为零的文件,读取错误为“操作无法完成。没有这样的文件或目录”。
我解决了这个问题。 该应用程序的文档目录有时已更改,因此文件的位置已更改。
文件保存在这里:
/var/mobile/Applications/09E7C349-6D03-4D2F-BE17-46C00B17C9F5/Documents/drafts/2014-08-13_12-57-57.m4a
然后在这里:
/var/mobile/Applications/1A444A31-C29D-4B0F-8B47-A5B57D7F3281/Documents/drafts/2014-08-16_20-45-06.m4a
请注意,应用程序的文件夹具有不同的令牌。 所以文件是“那里”,但我猜不是。 显然,当使用新的配置文件或应用程序商店有更新时,应用程序的目录可以更改(请参阅此答案 )。
因此,故事的寓意是:不要将绝对路径保存为对文件的引用。
好吧,我已经写了我想你要实现的目标。 请注意,在此示例中,加载文件的代码在主队列上同步完成(在某些viewDidAppear:方法中)。 对于实际代码,这当然是一个非常糟糕的设计,因为它可能会阻塞UI和主队列。 但这应该可行。 如果是这样,那么我认为您的代码在URL或加载文件时使用的选项方面存在一些问题。 如果此代码也不起作用,则可能是其他原因导致了问题。
干得好:
#import "ViewController.h"
NSString * const kDraftsDir = @"drafts";
@interface ViewController ()
@property (nonatomic, readonly) NSMutableArray * drafts;
@end
@implementation ViewController
@synthesize drafts = _drafts;
- (NSMutableArray *) drafts
{
if (nil == _drafts)
{
_drafts = [[NSMutableArray alloc] init];
}
return _drafts;
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear: animated];
[self readDrafts];
}
- (void) readDrafts
{
NSFileManager * fileManager = [[NSFileManager alloc] init];
NSError * error;
NSURL * appDocumentDirectoryURL = [fileManager URLForDirectory: NSDocumentDirectory
inDomain: NSUserDomainMask
appropriateForURL: nil
create: YES
error: &error];
if (nil == appDocumentDirectoryURL)
{
NSLog(@"Error getting appDocumentDirectoryURL: %@, %@", error, [error localizedDescription]);
}
NSURL * draftsDirectoryURL = [appDocumentDirectoryURL URLByAppendingPathComponent: kDraftsDir];
if ([fileManager fileExistsAtPath: draftsDirectoryURL.path isDirectory: NULL])
{
// the folder exists, there might be drafts
NSArray * files = [fileManager contentsOfDirectoryAtURL: draftsDirectoryURL
includingPropertiesForKeys: nil
options: NSDirectoryEnumerationSkipsHiddenFiles
error: &error];
if (nil == files)
{
NSLog(@"Error loading drafts from disk: %@, %@", error, [error localizedDescription]);
}
else
{
for (NSURL * aDraftURL in files)
{
// This is just a check for debugging purposes
NSData * draftData = [NSData dataWithContentsOfURL: aDraftURL];
if (draftData.length == 0)
{
NSLog(@"WARNING: no file, or zero-size file at URL: %@", aDraftURL);
}
NSMutableDictionary * draftDict = [[NSMutableDictionary alloc] init];
NSString * draftName = [[aDraftURL lastPathComponent]stringByDeletingPathExtension];
// let's make sure we won't crash because we are inserting nil into a dictionary
if (nil != draftName)
{
draftDict[@"draftFilename"] = [[aDraftURL lastPathComponent]stringByDeletingPathExtension];
}
else
{
NSLog(@"WARNING: no fileName without extension for draft at URL: %@", aDraftURL);
}
NSDate * creationDate = nil;
[aDraftURL getResourceValue: &creationDate forKey:NSURLCreationDateKey error:&error];
// let's make sure we won't crash because we are inserting nil into a dictionary
if (nil != creationDate)
{
draftDict[@"creationDate"] = creationDate;
}
else
{
NSLog(@"WARNING: no creationdate found for file at URL: %@", aDraftURL);
}
// self.drafts will always return a fully initialized NSMutableArray, so we
// can safely add an object at index 0
[self.drafts insertObject: draftDict atIndex: 0];
}
}
}
else
{
NSLog(@"The drafts folder does not exist.");
}
NSLog(@"%@ stored drafts: %@", @([self.drafts count]), self.drafts);
}
@end
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.