Check if the file is a Swift alias

How to check if a file is an alias on a Mac? Here is my code:

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()) } } 

How to check if there is a file and an alias?

+1
source share
2 answers

Update . I initially mistakenly assumed that the only option is to use the CoreFoundation (C API) method, but this is not true ( thanks ): the Foundation class (ObjC API) NSURL provides a way to detect Finder aliases:

 // 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? } 

[Not recommended, except for exercises when using UnsafeMutablePointer<Void> ]
Here's how to do it with the C-based CoreFoundation API:

  • IsAliasFile() deprecated in OS X 10.4,
  • succeeded FSIsAliasFile() , which is deprecated in 10.8.
  • The current method uses CFURLCopyResourcePropertyForKey() , which Swift is not fun to work with, because of the need to use manual memory management using UnsafeMutablePointer<Void> .

Hope I understood memory management correctly:

 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 } 
+2
source

There is a simple solution that is completely executed without pointer processing:

 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 } } 

Explanation: resourceValues(forKeys:) returns .isAliasFile and .isSymbolicLink for symbolic links, so you need to make sure that the former is returned and the latter is not checked for aliases. If the path does not exist, the function returns nil.

+1
source

Source: https://habr.com/ru/post/1234537/


All Articles