Ecco una funzione che non utilizza confronto tra stringhe per le date e precaricamenti la data di modifica nella enumeratore:
+ (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;
}
Se non si preoccupano i file che hai cancellato potresti farlo restituire BOOL
per indicare se ci sono stati errori, o semplicemente void
se vuoi solo fare un tentativo best-effort.
Per conservare selettivamente alcuni file, aggiungere un argomento di espressione regolare alla funzione che deve corrispondere ai file da conservare e aggiungere un controllo per quello nel ciclo while (sembra adattarsi meglio al caso d'uso), o se c'è una discreta quantità di file con modelli diversi che è possibile accettare uno NSSet
con i nomi file da conservare e controllare l'inclusione nel set prima di procedere all'eliminazione.
Anche solo menzionarlo qui perché potrebbe essere rilevante per alcuni: il file system su iOS e OSX non memorizza mtime con maggiore precisione di un secondo, quindi fai attenzione se hai bisogno di precisione millisecondo o simili.
corrispondente banco di prova per cadere nella vostra suite di test se si desidera:
@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");
}
Scorrere attraverso la directory, estrarre le date del file ed eliminare quelle più vecchie di un mese. Avere un elenco di file da confrontare per quelli che non si desidera eliminare. –
Sì. la stessa domanda è stata posta solo 3 giorni prima. –