2015-10-26 2 views
1

Как проверить, является ли файл псевдонимом на Mac? Вот мой код:Проверьте, является ли файл псевдонимом Swift

public func getFiles(){ 
    let folderPath = "/Users/timeBro/Desktop/testfolder" 
    let fileManager = NSFileManager.defaultManager() 
    let enumerator:NSDirectoryEnumerator = fileManager.enumeratorAtPath(folderPath)! 

    for url in enumerator.allObjects { 

     let newurl = NSURL(string: url as! String) 
     print("\(url as! String)") 
     print(url); 
     print(newurl?.isFileReferenceURL()) 
    } 
} 

Как проверить, есть ли файл и псевдоним?

+0

Вы правы. он работает, но я изменю это. проблема по-прежнему является псевдонимом – Silve2611

ответ

2

Update: я изначально ошибочно предположил, что единственным вариантом является использование метода CoreFoundation (C API), но это на самом деле не так (thanks): Foundation (ObjC API) класс NSURL не предусматривает способ обнаружения Finder псевдонимами:

// OSX 10.9+ 
// Indicates if the specified filesystem path is a Finder alias. 
// Returns an optional Boolean: if the lookup failed, such when the path doesn't exist, 
// nil is returned. 
// Example: isFinderAlias("/path/to/an/alias") 
func isFinderAlias(path:String) -> Bool? { 
    let aliasUrl = NSURL(fileURLWithPath: path) 
    var isAlias:AnyObject? = nil 
    do { 
     try aliasUrl.getResourceValue(&isAlias, forKey: NSURLIsAliasFileKey) 
    } catch _ {} 
    return isAlias as! Bool? 
} 

[Не рекомендуется, за исключением случаев, упражнения в использовании UnsafeMutablePointer<Void>]
Вот как это сделать с C-йоркского CoreFoundation API:

  • IsAliasFile() осуждался в OS X 10.4,
  • сменил FSIsAliasFile(), который осуждался в 10.8.
  • Текущий метод заключается в использовании CFURLCopyResourcePropertyForKey(), что не очень приятно иметь в Swift, из-за необходимости использовать ручное управление памятью с помощью UnsafeMutablePointer<Void>.

Я надеюсь, что я получил право управления памятью:

import Foundation 

// Indicates if the specified filesystem path is a Finder alias. 
// Returns an optional Boolean: if the lookup failed, such when the path 
// doesn't exist, nil is returned. 
// Example: isFinderAlias("/path/to/an/alias") 
func isFinderAlias(path:String) -> Bool? { 

    var isAlias:Bool? = nil // Initialize result var. 

    // Create a CFURL instance for the given filesystem path. 
    // This should never fail, because the existence isn't verified at this point. 
    // Note: No need to call CFRelease(fUrl) later, because Swift auto-memory-manages CoreFoundation objects. 
    let fUrl = CFURLCreateWithFileSystemPath(nil, path, CFURLPathStyle.CFURLPOSIXPathStyle, false) 

    // Allocate void pointer - no need for initialization, 
    // it will be assigned to by CFURLCopyResourcePropertyForKey() below. 
    let ptrPropVal = UnsafeMutablePointer<Void>.alloc(1) 

    // Call the CoreFoundation function that copies the desired information as 
    // a CFBoolean to newly allocated memory that prt will point to on return. 
    if CFURLCopyResourcePropertyForKey(fUrl, kCFURLIsAliasFileKey, ptrPropVal, nil) { 

     // Extract the Bool value from the memory allocated. 
     isAlias = UnsafePointer<CFBoolean>(ptrPropVal).memory as Bool 

     // Since the CF*() call contains the word "Copy", WE are responsible 
     // for destroying (freeing) the memory. 
     ptrPropVal.destroy() 
    } 

    // Deallocate the pointer 
    ptrPropVal.dealloc(1) 

    return isAlias 
} 
+0

Хорошее решение. Прежде чем я отправлю еще один вопрос. Как получить путь к файлу документа, на который указывает псевдоним? – Silve2611

+0

@ Silve2611: Это еще более привлекательно, поэтому я предлагаю вам задать новый вопрос; в документации говорится: «Сначала используйте CFURLCreateBookmarkDataFromFile, затем используйте CFURLCreateByResolvingBookmarkData». Не стесняйтесь сообщать мне об этом, как только вы задали новый вопрос, если вам все еще нужна помощь. – mklement0

+0

Хорошо. Я также сделал большую часть этого, но я только получил Fileid не путь. – Silve2611

1

Там есть простое решение, которое полностью обходится без обработки указателя:

extension URL { 
    func isAlias() -> Bool? { 
     let values = try? url.resourceValues(forKeys: [.isSymbolicLinkKey, .isAliasFileKey]) 
     let alias = values?.isAliasFile 
     let symbolic = values?.isSymbolicLink 

     guard alias != nil, symbolic != nil else { return nil } 
     if alias! && !symbolic! { 
      return true 
     } 
     return false 
    } 
} 

Объяснение: resourceValues(forKeys:) возвращает .isAliasFileи.isSymbolicLink для символических ссылок, поэтому вы должны убедиться, что первая была возвращена, а последняя не проверяется на псевдоним эс. Если путь не существует, функция возвращает nil.

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