Как проверить, существует ли каталог в Objective-C
Я думаю, что это проблема новичка, но я пытался проверить, существует ли каталог в моей папке документов на iPhone. Я прочитал документацию и придумал этот код, который, к сожалению, разбился с EXC_BAD_ACCESS в строке bool fileExists:
-(void)checkIfDirectoryAlreadyExists:(NSString *)name
{
NSFileManager *fileManager = [[NSFileManager alloc] init];
NSString *path = [[self documentsDirectory] stringByAppendingPathComponent:name];
BOOL fileExists = [fileManager fileExistsAtPath:path isDirectory:YES];
if (fileExists)
{
NSLog(@"Folder already exists...");
}
}
Я не понимаю, что я сделал не так? По-моему, все выглядит идеально, и это, безусловно, соответствует документам, не так ли? Любые откровения о том, где я ошибся, будут высоко оценены! Спасибо.
Обновлено:
Все еще не работает...
-(void)checkIfDirectoryAlreadyExists:(NSString *)name
{
NSFileManager *fileManager = [[NSFileManager alloc] init];
NSString *path = [[self documentsDirectory] stringByAppendingPathComponent:name];
BOOL isDir;
BOOL fileExists = [fileManager fileExistsAtPath:path isDirectory:&isDir];
if (fileExists)
{
if (isDir) {
NSLog(@"Folder already exists...");
}
}
}
3 ответа:
Посмотрите в документации для этой подписи метода:
- (BOOL)fileExistsAtPath:(NSString *)path isDirectory:(BOOL *)isDirectory
Вам нужен указатель на BOOL var в качестве аргумента, а не сам BOOL. NSFileManager будет записывать, является ли файл каталогом или нет в этой переменной. Например:
BOOL isDir; BOOL exists = [fm fileExistsAtPath:path isDirectory:&isDir]; if (exists) { /* file exists */ if (isDir) { /* file is a directory */ } }
На всякий случай, если кому-то нужен геттер, который создает папку в документах, если ее нет:
- (NSString *)folderPath { if (! _folderPath) { NSString *folderName = @"YourFolderName"; NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *documentsDirectoryPath = [documentPaths objectAtIndex:0]; _folderPath = [documentsDirectoryPath stringByAppendingPathComponent:folderName]; // if folder doesn't exist, create it NSError *error = nil; NSFileManager *fileManager = [NSFileManager defaultManager]; BOOL isDir; if (! [fileManager fileExistsAtPath:_folderPath isDirectory:&isDir]) { BOOL success = [fileManager createDirectoryAtPath:_folderPath withIntermediateDirectories:NO attributes:nil error:&error]; if (!success || error) { NSLog(@"Error: %@", [error localizedDescription]); } NSAssert(success, @"Failed to create folder at path:%@", _folderPath); } } return _folderPath; }
У меня есть служебный синглетный класс, который я использую для таких вещей. Поскольку я не могу обновить свою базу данных, если она остается в документах, я копирую свою .файлы sqlite из документов в / Library / Private Documents с помощью этого кода. Первый метод находит библиотеку. Второй создает папку Private Documents, если она не существует, и возвращает расположение в виде строки. Второй метод использует тот же метод файлового менеджера, что и @wzboson.
+ (NSString *)applicationLibraryDirectory { return [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) lastObject]; } + (NSString *)applicationLibraryPrivateDocumentsDirectory { NSError *error; NSString *PrivateDocumentsDirectory = [[self applicationLibraryDirectory] stringByAppendingPathComponent:@"Private Documents"]; BOOL isDir; if (! [[NSFileManager defaultManager] fileExistsAtPath:PrivateDocumentsDirectory isDirectory:&isDir]) { if (![[NSFileManager defaultManager] createDirectoryAtPath:PrivateDocumentsDirectory withIntermediateDirectories:NO attributes:nil error:&error]) { NSLog(@"Create directory error: %@", error); } } return PrivateDocumentsDirectory; }
Я использую его так в моем постоянном магазине инициализация координатора. Однако тот же принцип применим к любым файлам.
NSString *libraryDirectory = [Utilities applicationLibraryPrivateDocumentsDirectory]; NSString *sourcePath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:sqliteName]; NSString *destinationPath = [libraryDirectory stringByAppendingPathComponent:sqliteName];