检查文件是否为别名 Swift
Check if file is alias Swift
如何检查文件是否是 Mac 上的别名?到目前为止,这是我的代码:
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())
}
}
如何检查文件是否为别名?
Update:我最初错误地认为唯一的选择是使用 CoreFoundation (C API) 方法,但这实际上不是真的 ():Foundation (ObjC API) class 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>
.[=39 的手动内存管理=]
希望我的内存管理正确:
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
}
有一个简单的解决方案,无需任何指针处理即可完全解决:
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:)
returns .isAliasFile
和 .isSymbolicLink
用于符号链接所以你必须确保前者是返回,后者在检查别名时不返回。
如果路径不存在函数 returns nil.
如何检查文件是否是 Mac 上的别名?到目前为止,这是我的代码:
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())
}
}
如何检查文件是否为别名?
Update:我最初错误地认为唯一的选择是使用 CoreFoundation (C 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>
.[=39 的手动内存管理=]
希望我的内存管理正确:
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
}
有一个简单的解决方案,无需任何指针处理即可完全解决:
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:)
returns .isAliasFile
和 .isSymbolicLink
用于符号链接所以你必须确保前者是返回,后者在检查别名时不返回。
如果路径不存在函数 returns nil.