iOS - 如何有选择地删除文档目录中超过一个月的文件

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

我正在将图像下载到我的应用程序,几周之后用户就不会关心了。我将它们下载到应用程序中,这样就不必每次发布都下载它们。问题是我不希望Documents文件夹变得比它随时间变大。所以我认为我可以“清理”超过一个月的文件。

问题是,那里会有一些文件会超过一个月,但我不想删除。它们将是静态命名文件,因此它们很容易识别,只有3或4个。虽然我想删除几十个旧文件。这是一个例子:

picture.jpg           <--Older than a month DELETE
picture2.jpg          <--NOT older than a month Do Not Delete
picture3.jpg          <--Older than a month DELETE
picture4.jpg          <--Older than a month DELETE
keepAtAllTimes.jpg    <--Do not delete no matter how old
keepAtAllTimes2.jpg   <--Do not delete no matter how old
keepAtAllTimes3.jpg   <--Do not delete no matter how old

我怎样才能有选择地删除这些文件?

提前致谢!

iphone objective-c ios iphone-4
6个回答
12
投票

用于删除超过两天的文件的代码。最初我回答了here。我测试了它,它在我的项目中工作。

附:在删除Document目录中的所有文件之前要小心,因为这样做可能会导致丢失数据库文件(如果您正在使用.. !!),这可能会给您的应用程序带来麻烦。这就是为什么我保持条件在那里。 :-))

// Code to delete images older than two days.
   #define kDOCSFOLDER [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"]

NSFileManager* fileManager = [[[NSFileManager alloc] init] autorelease];
NSDirectoryEnumerator* en = [fileManager enumeratorAtPath:kDOCSFOLDER];    

NSString* file;
while (file = [en nextObject])
{
    NSLog(@"File To Delete : %@",file);
    NSError *error= nil;

    NSString *filepath=[NSString stringWithFormat:[kDOCSFOLDER stringByAppendingString:@"/%@"],file];


    NSDate   *creationDate =[[fileManager attributesOfItemAtPath:filepath error:nil] fileCreationDate];
    NSDate *d =[[NSDate date] dateByAddingTimeInterval:-1*24*60*60];

    NSDateFormatter *df=[[NSDateFormatter alloc]init];// = [NSDateFormatter initWithDateFormat:@"yyyy-MM-dd"];
    [df setDateFormat:@"EEEE d"]; 

    NSString *createdDate = [df stringFromDate:creationDate];

     NSString *twoDaysOld = [df stringFromDate:d];

    NSLog(@"create Date----->%@, two days before date ----> %@", createdDate, twoDaysOld);

    // if ([[dictAtt valueForKey:NSFileCreationDate] compare:d] == NSOrderedAscending)
    if ([creationDate compare:d] == NSOrderedAscending)

    {
        if([file isEqualToString:@"RDRProject.sqlite"])
        {

            NSLog(@"Imp Do not delete");
        }

        else
        {
             [[NSFileManager defaultManager] removeItemAtPath:[kDOCSFOLDER stringByAppendingPathComponent:file] error:&error];
        }
    }
}

4
投票

您可以获取文件创建日期,查看此SO Post然后只是比较日期。并为需要删除和不删除的文件创建两个不同的数组。


1
投票

我的两分钱值得。变更符合要求以适应。

func cleanUp() {
    let maximumDays = 10.0
    let minimumDate = Date().addingTimeInterval(-maximumDays*24*60*60)
    func meetsRequirement(date: Date) -> Bool { return date < minimumDate }

    func meetsRequirement(name: String) -> Bool { return name.hasPrefix(applicationName) && name.hasSuffix("log") }

    do {
        let manager = FileManager.default
        let documentDirUrl = try manager.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false)
        if manager.changeCurrentDirectoryPath(documentDirUrl.path) {
            for file in try manager.contentsOfDirectory(atPath: ".") {
                let creationDate = try manager.attributesOfItem(atPath: file)[FileAttributeKey.creationDate] as! Date
                if meetsRequirement(name: file) && meetsRequirement(date: creationDate) {
                    try manager.removeItem(atPath: file)
                }
            }
        }
    }
    catch {
        print("Cannot cleanup the old files: \(error)")
    }
}

0
投票

要查找文件的创建日期,您可以参考一个非常有用的StackOverflow帖子:

iOS: How do you find the creation date of a file?

请参阅此文章,这可能有助于您删除它们。您可以大致了解从文档目录中删除这些数据需要做些什么:

How to delete files from iPhone's document directory which are older more than two days

希望这对你有所帮助。


0
投票

这是一个函数,它不对日期使用字符串比较并预取枚举器中的修改时间:

+ (NSArray<NSURL *> *)deleteFilesOlderThan:(NSDate *)earliestDateAllowed
                               inDirectory:(NSURL *)directory {
    NSFileManager *fileManager = [NSFileManager defaultManager];
    NSDirectoryEnumerator<NSURL *> *enumerator =
        [fileManager enumeratorAtURL:directory
            includingPropertiesForKeys:@[ NSURLContentModificationDateKey ]
                               options:0
                          errorHandler:^BOOL(NSURL *_Nonnull url, NSError *_Nonnull error) {
                              NSLog(@"Failed while enumerating directory '%@' for files to "
                                         @"delete: %@ (failed on file '%@')",
                                         directory.path, error.localizedDescription, url.path);
                              return YES;
                          }];

    NSURL *file;
    NSError *error;
    NSMutableArray<NSURL *> *filesDeleted = [NSMutableArray new];
    while (file = [enumerator nextObject]) {
        NSDate *mtime;
        if (![file getResourceValue:&mtime forKey:NSURLContentModificationDateKey error:&error]) {
            NSLog(@"Couldn't fetch mtime for file '%@': %@", file.path, error);
            continue;
        }

        if ([earliestDateAllowed earlierDate:mtime] == earliestDateAllowed) {
            continue;
        }

        if (![fileManager removeItemAtURL:file error:&error]) {
            NSLog(@"Couldn't delete file '%@': %@", file.path, error.localizedDescription);
            continue;
        }
        [filesDeleted addObject:file];
    }
    return filesDeleted;
}

如果您不关心被删除的文件,您可以让它返回BOOL以指示是否有任何错误,或者只是void,如果您只是想尽力而为。

要有选择地保留一些文件,可以在函数中添加一个正则表达式参数,该参数应与要保留的文件匹配,并在while循环中添加一个检查(似乎最适合您的用例),或者是否存在离散量对于具有不同模式的文件,您可以接受带有文件名的NSSet,并在继续执行删除之前检查是否包含在集合中。

也只是在这里提到它,因为它可能与某些相关:iOS和OSX上的文件系统不会以超过一秒的精度存储mtime,因此如果您需要毫秒精度或类似精度,请注意。

如果您需要,可以将相应的测试用例放入测试套件中:

@interface MCLDirectoryUtilsTest : XCTestCase

@property NSURL *directory;

@end


@implementation MCLDirectoryUtilsTest

- (void)setUp {
    NSURL *tempdir = [NSURL fileURLWithPath:NSTemporaryDirectory() isDirectory:YES];
    self.directory = [tempdir URLByAppendingPathComponent:[NSUUID UUID].UUIDString isDirectory:YES];
    NSFileManager *fileManager = [NSFileManager defaultManager];
    [fileManager createDirectoryAtURL:self.directory
          withIntermediateDirectories:YES
                           attributes:nil
                                error:nil];
}


- (void)tearDown {
    NSFileManager *fileManager = [NSFileManager defaultManager];
    [fileManager removeItemAtURL:self.directory error:nil];
}


- (void)testDeleteFilesOlderThan {
    NSFileManager *fileManager = [NSFileManager defaultManager];
    // Create one old and one new file
    [fileManager createFileAtPath:[self.directory URLByAppendingPathComponent:@"oldfile"].path
                         contents:[NSData new]
                       attributes:@{
                           NSFileModificationDate : [[NSDate new] dateByAddingTimeInterval:-120],
                       }];
    [fileManager createFileAtPath:[self.directory URLByAppendingPathComponent:@"newfile"].path
                         contents:[NSData new]
                       attributes:nil];

    NSArray<NSURL *> *filesDeleted =
        [MCLUtils deleteFilesOlderThan:[[NSDate new] dateByAddingTimeInterval:-60]
                           inDirectory:self.directory];
    XCTAssertEqual(filesDeleted.count, 1);
    XCTAssertEqualObjects(filesDeleted[0].lastPathComponent, @"oldfile");
    NSArray<NSString *> *contentsInDirectory =
        [fileManager contentsOfDirectoryAtPath:self.directory.path error:nil];
    XCTAssertEqual(contentsInDirectory.count, 1);
    XCTAssertEqualObjects(contentsInDirectory[0], @"newfile");
}

0
投票

在Swift 3和4中,删除DocumentsDirectory中的特定文件

do{
    try FileManager.default.removeItem(atPath: theFile)
} catch let theError as Error{
    print("file not found \(theError)")
}
© www.soinside.com 2019 - 2024. All rights reserved.