Тестирование существования файла с использованием 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)
}
Имейте в виду, что это дорогостоящая операция, и она может быть устаревшей сразу после этого (если какой-то другой процесс удаляет или отключает файл диска, когда вы проверяете, существует ли он).
Как правило, предпочтительный подход заключается не в проверке, существует ли файл, а в том, чтобы просто попытаться прочитать или записать файл и обработать любую ошибку впоследствии, если она не удалась.