2009-12-18 5 views
68

Snow Leopard представил множество новых методов использования объектов NSURL для ссылки на файлы, а не на пути или FSRefs основных служб.Проверка существования файла с использованием NSURL

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

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

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

Есть ли простой способ или функция в Cocoa, CF или Core Services, которые гарантированы/задокументированы, чтобы сообщить мне, относится ли данный файл (или ссылка на файл) к существующему объекту файловой системы?

ответ

130

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]; 
+3

Для всех разработчиков ОС iPhone, отбрасываемых этим ответом: 'checkResourceIsReachableAndReturnError:' доступен только в 10.6 и более поздних версиях и еще не доступен в iPhone SDK. –

+4

Обновление: доступно на iOS 4. –

+2

Документы iOS в XCode 3.2.5 (который поддерживает iOS 4.2): «Этот метод не реализован в iOS, поэтому он не выполняет никаких операций». – Daniel

1

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

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

+0

Вы можете связать вышеупомянутый 'checkResourceIsReachableAndReturn Ошибка: 'с' isFileURL', чтобы сохранить работоспособность. –

2

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

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

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

An example would be periodic maintenance of UI state that depends on the existence of a particular document. When performing an operation such as opening a file, it is more efficient to simply try the operation and handle failures than to check first for reachability.

+1

Я сомневаюсь, что это медленно ... NSURL поддерживает ссылку на запись файловой системы HFS +, которую она представляет. Согласно Apple, URL-адреса * намного быстрее, чем пути для всех операций с файловой системой. –

29

КСН я не мог найти какой-либо другой способ ...

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

Вот Swift 2 Ответ:

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

Это должно быть 'checkResourceIsReachable() -> Void' и исключение исключения, однако, то, что вы сказали правильно для Xcode 7.x –

+0

* throw error. Быстрые ошибки отличаются от исключений Objective-C. Подобный синтаксис, но различная цель. –

Смежные вопросы