iOS-как выборочно удалять файлы старше месяца в каталоге документов
я загружаю изображения в свое приложение, которое через несколько недель пользователю будет все равно. Я загружаю их в приложение, поэтому их не нужно будет загружать при каждом запуске. Проблема в том, что я не хочу, чтобы папка документов становилась больше, чем она должна со временем. Поэтому я подумал, что могу" очистить " файл старше месяца.
проблема в том, что там будет несколько файлов, которые будут старше месяца, но которые я не хочу удалять. Они будут статические файлы так их будет легко идентифицировать, и их будет только 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
Как я могу выборочно удалить эти файлы?
спасибо заранее!
6 ответов
код для удаления файлов, которые старше двух дней. Первоначально я ответил здесь. Я протестировал его, и он работал в моем проекте.
P.S. будьте осторожны, прежде чем удалять все файлы в каталоге документов, потому что это может привести к потере файла базы данных(Если вы используете..!!), которая может вызвать проблемы для вашего приложения. Вот почему я сохранил там условие if. : -))
// 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];
}
}
}
вы можете получить дату создания файла, посмотри на это Так пост а затем просто сравните даты. и создайте два разных массива для файлов, которые должны быть удалены и не должны быть удалены..
мои два цента. Измените meetsRequirement в соответствии.
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)")
}
}
чтобы найти дату создания вашего файла, вы можете обратиться к очень полезному сообщению StackOverflow:
iOS: Как найти дату создания файла?
обратитесь к этому сообщению, это может помочь вам в их удалении. Вы можете просто получить приблизительное представление о том, что нужно сделать для удаления этих данных из каталога документов:
как удалить файлы из каталога документов iPhone, которые старше более двух дни
надеюсь, это поможет вам.
вот функция, которая не использует сравнение строк для дат и предваряет время изменения в перечислителе:
+ (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");
}
в Swift 3 и 4, чтобы удалить определенный файл в DocumentsDirectory
do{
try FileManager.default.removeItem(atPath: theFile)
} catch let theError as Error{
print("file not found \(theError)")
}