【问题标题】:How to find out if the NSURL is a directory or not如何判断 NSURL 是否为目录
【发布时间】:2014-04-12 04:41:45
【问题描述】:

我有一个 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");

【问题讨论】:

    标签: objective-c file directory nsurl nsfilemanager


    【解决方案1】:
    NSNumber *isDirectory;
    
    // this method allows us to get more information about an URL. 
    // We're passing NSURLIsDirectoryKey as key because that's 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's indeed a directory
    if (success && [isDirectory boolValue]) {
        NSLog(@"Congratulations, it's a directory!");
    } else {
        NSLog(@"It seems it's just a file.");
    }
    

    【讨论】:

    • 感谢您的回答,它运行良好,但是,作为 Objective C 的新手(而不是编程),我似乎无法理解。你能详细说明它是如何工作的吗?
    • 这很好 /only/ 如果文件或目录存在。否则你会得到一个错误,并对 URL /represents/ 做出不正确的假设
    • 即使目录存在,沙盒应用程序也可能无法访问它。因此,从 getResourceValue: 获得有效结果取决于 url 是否安全。
    【解决方案2】:

    使用 Swift 5,您可以使用以下 macOS Playground 示例代码之一检查 URL 路径是代表目录还是常规文件。


    #1。使用URLhasDirectoryPath 属性

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

    #2。使用FilemanagerattributesOfItem(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。使用FileManagerfileExists(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)
    

    【讨论】:

    • #1 和#3 是我的两个答案,#2 和#4 要求目录实际存在于文件系统中(而问题和其他答案并未做出此假设)。 ;)
    • 在沙盒应用程序中,所有这些操作的结果取决于 URL 是否安全(即受信任)。如果无法到达url指向的目录,则不会有文件夹斜线。
    【解决方案3】:

    开始[iOS 9, macOS 10.11, tvOS 9.0, watchOS 2.0],有hasDirectoryPath:

    url.hasDirectoryPath
    

    【讨论】:

      【解决方案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:@"/"] 是测试。

      【讨论】:

      • 请注意,在 iOS 8 中,如果 URL 表示磁盘上不存在的目录,则 URLByStandardizingPath 将 去除尾部斜杠测试无效。如果 URL 表示 确实 存在的目录,iOS 8 会留下斜线。 iOS 9 在这两种情况下都保留了斜线。
      • 还要注意,在沙盒应用程序中,URLByStandardizingPath 的结果取决于 url 是否安全(即受信任)。如果无法到达url指向的目录,则不会有文件夹斜线。
      【解决方案5】:

      从 iOS 8 开始,在 Swift 3 中,有 isDirectory:

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

      【讨论】:

        猜你喜欢
        • 2017-01-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-04-01
        • 2014-08-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多