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

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

提前致谢!

4

6 回答 6

14

删除超过两天的文件的代码。原来我在这里回答。我测试了它,它在我的项目中工作。

PS 在删除 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];
        }
    }
}
于 2012-04-12T19:07:26.233 回答
4

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

于 2012-04-12T17:32:29.053 回答
2

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

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)")
    }
}
于 2018-03-05T17:06:59.057 回答
0

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

iOS:如何找到文件的创建日期?

请参阅此帖子,这可能会帮助您删除它们。您可以大致了解从 Documents Directory 中删除这些数据需要做什么:

如何从 iPhone 的文档目录中删除超过两天的文件

希望这对您有所帮助。

于 2012-04-12T18:59:54.167 回答
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");
}
于 2016-08-10T19:02:25.143 回答
0

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

do{
    try FileManager.default.removeItem(atPath: theFile)
} catch let theError as Error{
    print("file not found \(theError)")
}
于 2017-06-28T06:03:02.703 回答