繁体   English   中英

应用程序文档目录中的空文件

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM