Swift 检查NSURL是否为目录

Swift 检查NSURL是否为目录,swift,nsurl,Swift,Nsurl,使用Swift时,我想检查NSURL位置是否为目录。对于Objective-C,这不是一个问题,但当我将代码转换为Swift时,会出现运行时错误 也许有人能给我指出正确的方向 import Foundation let defaultManager = NSFileManager.defaultManager() let documentsDirectory = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory

使用Swift时,我想检查
NSURL
位置是否为目录。对于Objective-C,这不是一个问题,但当我将代码转换为Swift时,会出现运行时错误

也许有人能给我指出正确的方向

import Foundation

let defaultManager = NSFileManager.defaultManager()
let documentsDirectory = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)[0] as NSURL
let localDocumentURLs = defaultManager.contentsOfDirectoryAtURL(documentsDirectory,
includingPropertiesForKeys: nil, options: .SkipsPackageDescendants, error: nil) as NSURL[]

for url in localDocumentURLs {
    var isError: NSError? = nil
    var isDirectory: AutoreleasingUnsafePointer<AnyObject?> = nil
    var success: Bool = url.getResourceValue(isDirectory, forKey: NSURLIsDirectoryKey, error: &isError)
}
<代码>导入基础 让defaultManager=NSFileManager.defaultManager() 将documentsDirectory=NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory,inDomains:.UserDomainMask)[0]设为NSURL 让localDocumentURLs=defaultManager.ContentsDirectoryAttribute(documentsDirectory, includingPropertiesForKeys:nil,选项:。SkipPackageDescendants,错误:nil)作为NSURL[] 对于LocalDocumentURL中的url{ var isError:N错误?=nil var isDirectory:AutoreleasingUnsafePointer=nil var成功:Bool=url.getResourceValue(isDirectory,forKey:NSURLIsDirectoryKey,error:&isError) }
在我这方面效果很好:

var error: NSError?
let documentURL : NSURL = NSFileManager.defaultManager().URLForDirectory(NSSearchPathDirectory.DocumentDirectory, inDomain: NSSearchPathDomainMask.UserDomainMask, appropriateForURL: nil, create: true, error: &error)
var isDirectory: ObjCBool = ObjCBool(0)
if NSFileManager.defaultManager().fileExistsAtPath(documentURL.path, isDirectory: &isDirectory) {
    println(isDirectory)
}
注意:它检查
文档
文件夹是否为文件夹。当然,您可以将URL替换为任何内容。

我的2美分。。。 swift NSURL方式:(基于holex的回答)


以下是原始海报代码的swift 2.0版本:

        do {
            var rsrc: AnyObject?
            try element.getResourceValue(&rsrc, forKey: NSURLIsDirectoryKey)
            if let isDirectory = rsrc as? NSNumber {
                if isDirectory == true {
                    // ...
                }
            }
        } catch {
        }

在iOS 9.0+和macOS 10.11+中,
NSURL
/
URL

Swift:

var hasDirectoryPath: Bool { get }
@property(readonly) BOOL hasDirectoryPath;
let isDirectory = (try? url.resourceValues(forKeys: [.isDirectoryKey]))?.isDirectory ?? false
NSNumber *isDirectory = nil;
[url getResourceValue:&isDirectory forKey:NSURLIsDirectoryKey error:nil];
NSLog(@"%i", isDirectory.boolValue);
目标-C:

var hasDirectoryPath: Bool { get }
@property(readonly) BOOL hasDirectoryPath;
let isDirectory = (try? url.resourceValues(forKeys: [.isDirectoryKey]))?.isDirectory ?? false
NSNumber *isDirectory = nil;
[url getResourceValue:&isDirectory forKey:NSURLIsDirectoryKey error:nil];
NSLog(@"%i", isDirectory.boolValue);
但是,这仅适用于使用
FileManager
API创建的url,该API确保字典的字符串路径以斜杠结尾

对于使用自定义文字字符串路径创建的URL,最好读取资源值
isDirectory

Swift:

var hasDirectoryPath: Bool { get }
@property(readonly) BOOL hasDirectoryPath;
let isDirectory = (try? url.resourceValues(forKeys: [.isDirectoryKey]))?.isDirectory ?? false
NSNumber *isDirectory = nil;
[url getResourceValue:&isDirectory forKey:NSURLIsDirectoryKey error:nil];
NSLog(@"%i", isDirectory.boolValue);
目标-C:

var hasDirectoryPath: Bool { get }
@property(readonly) BOOL hasDirectoryPath;
let isDirectory = (try? url.resourceValues(forKeys: [.isDirectoryKey]))?.isDirectory ?? false
NSNumber *isDirectory = nil;
[url getResourceValue:&isDirectory forKey:NSURLIsDirectoryKey error:nil];
NSLog(@"%i", isDirectory.boolValue);

这里有很多答案。。。但它们都有一个共同点:
它们都使用
FileManager
(实际上是
nsfilemanager

这种方法有一个缺点:
FileManager
不是线程安全的
并行使用来自不同线程的
文件管理器
通常适用于无状态操作,但这并不能保证(当您依赖于未定义的行为时,您可能正在构建该操作)

一个安全的实现每次都必须创建一个新的
FileManager
实例,但这会带来糟糕的性能,或者每个线程使用一个实例,这会带来巨大的管理开销

我想在这里介绍一种更好、更简单的方法,它不需要任何第三方类:

extension URL {
    var isDirectory: Bool? {
        do {
            let values = try self.resourceValues(
                forKeys:Set([URLResourceKey.isDirectoryKey])
            )
            return values.isDirectory
        } catch  { return nil }
    }
}

就这样。使用
resourceValues()
方法,您还可以轻松查询其他有趣的信息,如文件大小或上次修改日期。这是一个非常强大的API,在Obj-C中,NSURL的
NSURL
也存在很多年。。。这是
文件管理器上的Swift 3扩展:

extension FileManager {
    func isDirectory(url:URL) -> Bool? {
        var isDir: ObjCBool = ObjCBool(false)
        if fileExists(atPath: url.path, isDirectory: &isDir) {
            return isDir.boolValue
        } else {
            return nil
        }
    }
}
斯威夫特3

extension URL {
    var isDirectory: Bool {
        let values = try? resourceValues(forKeys: [.isDirectoryKey])
        return values?.isDirectory ?? false
    }
}

运行时错误到底发生在哪里?thx,这种方法正在工作-我做了一些小的修改,因为NSFileManager.defaultManager().fileExistsAtPath(url.path,isDirectory:&isDirectory)在我的情况下返回allows true?isDirectory实际上保存了真实的信息。非常感谢您的帮助。是的,
fileExistsAtPath()
返回路径是否存在,
isDirectory
将保存路径是否为文件夹的信息。Man。。。我正在做<代码> var ISDR:ObjcBOOL = Value<代码> > var ISDR: ObjcBOOL = ObjbOOL(0)< /代码>现在我明白,<代码> false 和<代码>真/ <代码>被自动桥接到NSCONT而不是ObjcBOOL。真的很遗憾,这个答案只出现在中间的某个地方。@ ToMaskiLIN在2014被问答。iOS9大约一年后发布了,这就是今天的答案。因此,我经常在这里得到正确答案,答案介于两者之间,而不是顶部。此属性不会查看文件系统以确定URL是否实际指向目录:
URL(字符串):file:///var/")!.hasDirectoryPath
true
(注意后面的
/
),而
URL(字符串:file:///var")!.hasDirectoryPath
false
。检查
resourceValues
是更好的方法。真正的答案无疑是确定答案的最佳方法!