Как узнать, является ли NSURL каталогом или нет

У меня есть объект NSURL. У него есть адрес элемента файловой системы, это либо файл, либо каталог. Я хочу быть в состоянии сказать, является ли NSURL каталогом или файлом.

Я уже попробовал это, которое, кажется, не работает!

NSURL * temp ....... ;// it is initialized and has a valid value 
CFURLRef xx = (CFURLRef)CFBridgingRetain(temp);
if(CFURLHasDirectoryPath(xx)) NSLog(@"was a file");
else NSLog(@"was a folder");

Ответ 1

NSNumber *isDirectory;

// this method allows us to get more information about an URL. 
// We're passing NSURLIsDirectoryKey as key because that the info we want to know.
// Also, we pass a reference to isDirectory variable, so it can be modified to have the return value
BOOL success = [url getResourceValue:&isDirectory forKey:NSURLIsDirectoryKey error:nil];

// If we could read the information and it indeed a directory
if (success && [isDirectory boolValue]) {
    NSLog(@"Congratulations, it a directory!");
} else {
    NSLog(@"It seems it just a file.");
}

Ответ 2

Начиная с [iOS 9, macOS 10.11, tvOS 9.0, watchOS 2.0], есть hasDirectoryPath:

url.hasDirectoryPath

Ответ 3

В Swift 5 вы можете проверить, представляет ли путь URL каталог или обычный файл, используя один из следующих примеров кодов MacOS Playground.


# 1. Использование свойства URL hasDirectoryPath

import Foundation

let url = URL(fileURLWithPath: "/Users/User/Desktop")
print("is directory:", url.hasDirectoryPath)

# 2. Использование Filemanager attributesOfItem(atPath:)

import Foundation

let url = URL(fileURLWithPath: "/Users/User/Desktop/File.pdf")
let attributes = try! FileManager.default.attributesOfItem(atPath: url.path)
if let type = attributes[FileAttributeKey.type] as? FileAttributeType {
    print("is file:", type == FileAttributeType.typeRegular)
}
import Foundation

let url = URL(fileURLWithPath: "/Users/User/Desktop")
let attributes = try! FileManager.default.attributesOfItem(atPath: url.path)
if let type = attributes[FileAttributeKey.type] as? FileAttributeType {
    print("is directory:", type == FileAttributeType.typeDirectory)
}

# 3. Использование URLResourceValues

import Foundation

let url = URL(fileURLWithPath: "/Users/User/Desktop")
if let resources = try? url.resourceValues(forKeys: [.isDirectoryKey]) {
    let isDirectory = resources.isDirectory ?? false
    print(isDirectory)
} else {
    print("No such file or directory")
}
import Foundation

let url = URL(fileURLWithPath: "/Users/User/Desktop/File.pdf")
if let resources = try? url.resourceValues(forKeys: [.isRegularFileKey]) {
    let isFile = resources.isRegularFile ?? false
    print(isFile)
} else {
    print("No such file or directory")
}

# 4. Использование FileManager fileExists(atPath:isDirectory:)

import Foundation

let url = URL(fileURLWithPath: "/Users/User/Desktop")
var isDirectory: ObjCBool = false
let fileExists = FileManager.default.fileExists(atPath: url.path, isDirectory: &isDirectory)
print("is directory:", fileExists && isDirectory.boolValue)

Ответ 4

Если вы знаете, что URL-адрес файла был стандартизован, вы можете проверить завершающую косую черту.

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

Вот тест, который показывает -URLByStandardizingPath добавление конечной косой черты:

// Get a directory, any directory will do
NSURL *initialURL = [[NSBundle mainBundle] bundleURL];
NSString *initialString = [initialURL absoluteString];

// String the trailing slash off the directory
NSString *directoryString = [initialString substringToIndex:[initialString length] - 1];
NSURL *directoryURL = [NSURL URLWithString:directoryString];

XCTAssertFalse([[directoryURL absoluteString] hasSuffix:@"/"],
               @"directoryURL should not end with a slash");

XCTAssertTrue([[[directoryURL URLByStandardizingPath] absoluteString] hasSuffix:@"/"],
              @"[directoryURL URLByStandardizingPath] should end with a slash");

Как вы можете видеть, [[[directoryURL URLByStandardizingPath] absoluteString] hasSuffix:@"/"] - это тест.

Ответ 5

Запуск iOS 8, в Swift 3, isDirectory:

(try? url.resourceValues(forKeys: [.isDirectoryKey]))?.isDirectory ?? false