我正在将图像下载到我的应用程序,几周之后用户就不会关心了。我将它们下载到应用程序中,这样就不必每次发布都下载它们。问题是我不希望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
我怎样才能有选择地删除这些文件?
提前致谢!
用于删除超过两天的文件的代码。最初我回答了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];
}
}
}
您可以获取文件创建日期,查看此SO Post然后只是比较日期。并为需要删除和不删除的文件创建两个不同的数组。
我的两分钱值得。变更符合要求以适应。
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: 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
希望这对你有所帮助。
这是一个函数,它不对日期使用字符串比较并预取枚举器中的修改时间:
+ (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)")
}