Тестирование существования файла с использованием NSURL

В Snow Leopard появилось много новых методов использования объектов NSURL для ссылки на файлы, а не на имена путей или FSRefs Core Services.

Тем не менее, есть одна задача, для которой я не могу найти метод на основе URL: Проверка, существует ли файл. Я ищу версию на основе URL - [NSFileManager fileExistsAtPath: ]. Как и этот метод, он должен вернуть YES если URL-адрес описывает что-либо, будь то обычный файл, каталог или что-то еще.

Я мог бы попытаться найти различные значения ресурсов, но ни одно из них явно не гарантировано не существует, если файл не существует, и некоторые из них (например, NSURLEffectiveIconKey) могут быть дорогостоящими, если это так.

Я мог бы просто использовать NSFileManager's fileExistsAtPath:, но если есть более современный метод, я бы предпочел использовать его.

Существует ли простой метод или функция в Какао, CF или Базовых Службах, которые гарантированно / задокументированы, чтобы сказать мне, относится ли данный файл (или ссылка на файл) к объекту файловой системы, который существует?

6 ответов

Решение

NSURL имеет этот метод:

- (BOOL)checkResourceIsReachableAndReturnError:(NSError **)error

Какой "Возвращает, может ли быть достигнут ресурс, на который указывает URL файла".

NSURL *theURL = [NSURL fileURLWithPath:@"/Users/elisevanlooij/nonexistingfile.php" 
               isDirectory:NO];
NSError *err;
if ([theURL checkResourceIsReachableAndReturnError:&err] == NO)
    [[NSAlert alertWithError:err] runModal];

На iOS я не мог найти другой способ...

NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"file.type"];
if ([[NSFileManager defaultManager] fileExistsAtPath:[storeURL path]]) {...}

Вот ответ Swift 2:

var error:NSError?
let folderExists = theURL.checkResourceIsReachableAndReturnError(&error)

Определение того, ссылается ли данный URL-адрес файла (или ссылки на файл) на существующий объект файловой системы, является дорогостоящим для удаленных ресурсов, API-интерфейсы только 10.6 (без iPhoneOS) для этого CFURLResourceIsReachable() и [NSURL checkResourceIsReachableAndReturnError:] являются синхронными Даже если вы будете их использовать, для многих файлов вы все равно будете смотреть со значительной задержкой.

Что вы должны сделать, это реализовать собственную процедуру асинхронной проверки с кэшированием, которая отдельно создает список допустимых ресурсов.

В противном случае примечания для CFURLResourceIsReachable в состоянии заголовка:

Примером может служить периодическое поддержание состояния пользовательского интерфейса, которое зависит от существования конкретного документа. При выполнении такой операции, как открытие файла, более эффективно просто попытаться выполнить операцию и обработать сбои, чем сначала проверить доступность.

Поскольку NSURL может представлять больше, чем локальные файловые системы, я не думаю, что существует универсальный метод, который может проверять их существование надежным способом. По крайней мере, фонд Какао не содержит такой функции (насколько я знаю).

Если вы имеете дело только с локальными файловыми системами, я предлагаю вам создать категорию для NSURL или для NSFileManagerс urlExists: сообщение. Было бы преобразовать NSURL к NSString (нормализованный путь), а затем вызвать [NSFileManager fileExistsAtPath:] сообщение.

В Swift вы можете использовать checkResourceIsReachable() метод, который, к сожалению, либо вернет true (если файл доступен) или выведите ошибку (объясняющую, почему он не может быть достигнут).

Чтобы получить значение bool true/false вместо этого, используйте этот синтаксис:

let exists = (try? inputFile.checkResourceIsReachable()) ?? false

Если вы хотите записать ошибку:

let exists: Bool
do {
  exists = try inputFile.checkResourceIsReachable()
} catch {
  exists = false
  print(error.localizedDescription)
}

Имейте в виду, что это дорогостоящая операция, и она может быть устаревшей сразу после этого (если какой-то другой процесс удаляет или отключает файл диска, когда вы проверяете, существует ли он).

Как правило, предпочтительный подход заключается не в проверке, существует ли файл, а в том, чтобы просто попытаться прочитать или записать файл и обработать любую ошибку впоследствии, если она не удалась.

Другие вопросы по тегам