Oto funkcja, która nie korzysta z porównania ciągów znaków dla dat i wstępnie wyłapuje czas modyfikacji w wyliczający:
+ (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;
}
Jeśli nie dbają o plikach usunięty, możesz zwrócić go BOOL
, aby wskazać, czy wystąpiły jakieś błędy, lub po prostu void
, jeśli chcesz zrobić próbę najlepszego wysiłku.
Aby zachować wybiórczo niektóre pliki, dodaj argument wyrażenia regularnego do funkcji, która powinna pasować do przechowywanych plików, i dodaj zaznaczenie w pętli while (najlepiej pasuje do Twojego przypadku użycia) lub istnieje dyskretna liczba plików o różnych wzorach, które można zaakceptować NSSet
wraz z nazwami plików, aby zachować i sprawdzić, czy zostały włączone do zestawu przed przystąpieniem do usuwania.
Także wspominając o tym tutaj, ponieważ może to być istotne dla niektórych: System plików na iOS i OSX nie przechowuje mtime z większą precyzją niż sekundę, więc uważaj na to, jeśli potrzebujesz dokładności milisekundy lub podobnej.
Odpowiadający przypadek test spadek do swojego zestawu testowego, jeśli chcesz:
@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");
}
Przejrzyj katalog, wyodrębnij daty plików i usuń starsze niż miesiąc. Mieć listę plików do porównania dla tych, których nie chcesz usunąć. –
Tak. to samo pytanie zadano zaledwie 3 dni wcześniej. –