我正在寻找一个解决方案来为swift中的文件添加扩展文件属性.我查了这个链接写扩展文件属性,但解决方案是客观的c,我需要一个swift的解决方案.
Mar*_*n R 31
以下是Swift 3中作为扩展的可能实现URL,具有获取,设置,列出和删除文件的扩展属性的方法.(Swift 2代码可以在下面找到.)
extension URL {
/// Get extended attribute.
func extendedAttribute(forName name: String) throws -> Data {
let data = try self.withUnsafeFileSystemRepresentation { fileSystemPath -> Data in
// Determine attribute size:
let length = getxattr(fileSystemPath, name, nil, 0, 0, 0)
guard length >= 0 else { throw URL.posixError(errno) }
// Create buffer with required size:
var data = Data(count: length)
// Retrieve attribute:
let result = data.withUnsafeMutableBytes { [count = data.count] in
getxattr(fileSystemPath, name, $0.baseAddress, count, 0, 0)
}
guard result >= 0 else { throw URL.posixError(errno) }
return data
}
return data
}
/// Set extended attribute.
func setExtendedAttribute(data: Data, forName name: String) throws {
try self.withUnsafeFileSystemRepresentation { fileSystemPath in
let result = data.withUnsafeBytes {
setxattr(fileSystemPath, name, $0.baseAddress, data.count, 0, 0)
}
guard result >= 0 else { throw URL.posixError(errno) }
}
}
/// Remove extended attribute.
func removeExtendedAttribute(forName name: String) throws {
try self.withUnsafeFileSystemRepresentation { fileSystemPath in
let result = removexattr(fileSystemPath, name, 0)
guard result >= 0 else { throw URL.posixError(errno) }
}
}
/// Get list of all extended attributes.
func listExtendedAttributes() throws -> [String] {
let list = try self.withUnsafeFileSystemRepresentation { fileSystemPath -> [String] in
let length = listxattr(fileSystemPath, nil, 0, 0)
guard length >= 0 else { throw URL.posixError(errno) }
// Create buffer with required size:
var namebuf = Array<CChar>(repeating: 0, count: length)
// Retrieve attribute list:
let result = listxattr(fileSystemPath, &namebuf, namebuf.count, 0)
guard result >= 0 else { throw URL.posixError(errno) }
// Extract attribute names:
let list = namebuf.split(separator: 0).compactMap {
$0.withUnsafeBufferPointer {
$0.withMemoryRebound(to: UInt8.self) {
String(bytes: $0, encoding: .utf8)
}
}
}
return list
}
return list
}
/// Helper function to create an NSError from a Unix errno.
private static func posixError(_ err: Int32) -> NSError {
return NSError(domain: NSPOSIXErrorDomain, code: Int(err),
userInfo: [NSLocalizedDescriptionKey: String(cString: strerror(err))])
}
}
Run Code Online (Sandbox Code Playgroud)
用法示例:
let fileURL = URL(fileURLWithPath: "/path/to/file")
let attr1 = "com.myCompany.myAttribute"
let attr2 = "com.myCompany.otherAttribute"
let data1 = Data([1, 2, 3, 4])
let data2 = Data([5, 6, 7, 8, 9])
do {
// Set attributes:
try fileURL.setExtendedAttribute(data: data1, forName: attr1)
try fileURL.setExtendedAttribute(data: data2, forName: attr2)
// List attributes:
let list = try fileURL.listExtendedAttributes()
print(list)
// ["com.myCompany.myAttribute", "com.myCompany.otherAttribute", "other"]
let data1a = try fileURL.extendedAttribute(forName: attr1)
print(data1a as NSData)
// <01020304>
// Remove attributes
for attr in list {
try fileURL.removeExtendedAttribute(forName: attr)
}
} catch let error {
print(error.localizedDescription)
}
Run Code Online (Sandbox Code Playgroud)
(Swift 2的上一个答案:)
一个简单的例子:
extension URL {
/// Get extended attribute.
func extendedAttribute(forName name: String) throws -> Data {
let data = try self.withUnsafeFileSystemRepresentation { fileSystemPath -> Data in
// Determine attribute size:
let length = getxattr(fileSystemPath, name, nil, 0, 0, 0)
guard length >= 0 else { throw URL.posixError(errno) }
// Create buffer with required size:
var data = Data(count: length)
// Retrieve attribute:
let result = data.withUnsafeMutableBytes { [count = data.count] in
getxattr(fileSystemPath, name, $0.baseAddress, count, 0, 0)
}
guard result >= 0 else { throw URL.posixError(errno) }
return data
}
return data
}
/// Set extended attribute.
func setExtendedAttribute(data: Data, forName name: String) throws {
try self.withUnsafeFileSystemRepresentation { fileSystemPath in
let result = data.withUnsafeBytes {
setxattr(fileSystemPath, name, $0.baseAddress, data.count, 0, 0)
}
guard result >= 0 else { throw URL.posixError(errno) }
}
}
/// Remove extended attribute.
func removeExtendedAttribute(forName name: String) throws {
try self.withUnsafeFileSystemRepresentation { fileSystemPath in
let result = removexattr(fileSystemPath, name, 0)
guard result >= 0 else { throw URL.posixError(errno) }
}
}
/// Get list of all extended attributes.
func listExtendedAttributes() throws -> [String] {
let list = try self.withUnsafeFileSystemRepresentation { fileSystemPath -> [String] in
let length = listxattr(fileSystemPath, nil, 0, 0)
guard length >= 0 else { throw URL.posixError(errno) }
// Create buffer with required size:
var namebuf = Array<CChar>(repeating: 0, count: length)
// Retrieve attribute list:
let result = listxattr(fileSystemPath, &namebuf, namebuf.count, 0)
guard result >= 0 else { throw URL.posixError(errno) }
// Extract attribute names:
let list = namebuf.split(separator: 0).compactMap {
$0.withUnsafeBufferPointer {
$0.withMemoryRebound(to: UInt8.self) {
String(bytes: $0, encoding: .utf8)
}
}
}
return list
}
return list
}
/// Helper function to create an NSError from a Unix errno.
private static func posixError(_ err: Int32) -> NSError {
return NSError(domain: NSPOSIXErrorDomain, code: Int(err),
userInfo: [NSLocalizedDescriptionKey: String(cString: strerror(err))])
}
}
Run Code Online (Sandbox Code Playgroud)
在命令行上验证结果:
let fileURL = URL(fileURLWithPath: "/path/to/file")
let attr1 = "com.myCompany.myAttribute"
let attr2 = "com.myCompany.otherAttribute"
let data1 = Data([1, 2, 3, 4])
let data2 = Data([5, 6, 7, 8, 9])
do {
// Set attributes:
try fileURL.setExtendedAttribute(data: data1, forName: attr1)
try fileURL.setExtendedAttribute(data: data2, forName: attr2)
// List attributes:
let list = try fileURL.listExtendedAttributes()
print(list)
// ["com.myCompany.myAttribute", "com.myCompany.otherAttribute", "other"]
let data1a = try fileURL.extendedAttribute(forName: attr1)
print(data1a as NSData)
// <01020304>
// Remove attributes
for attr in list {
try fileURL.removeExtendedAttribute(forName: attr)
}
} catch let error {
print(error.localizedDescription)
}
Run Code Online (Sandbox Code Playgroud)
以下是如何获取和设置文件属性,实现为以下扩展方法URL:
extension URL {
/// Get extended attribute.
func extendedAttribute(forName name: String) throws -> Data {
let data = try self.withUnsafeFileSystemRepresentation { fileSystemPath -> Data in
// Determine attribute size:
let length = getxattr(fileSystemPath, name, nil, 0, 0, 0)
guard length >= 0 else { throw URL.posixError(errno) }
// Create buffer with required size:
var data = Data(count: length)
// Retrieve attribute:
let result = data.withUnsafeMutableBytes { [count = data.count] in
getxattr(fileSystemPath, name, $0.baseAddress, count, 0, 0)
}
guard result >= 0 else { throw URL.posixError(errno) }
return data
}
return data
}
/// Set extended attribute.
func setExtendedAttribute(data: Data, forName name: String) throws {
try self.withUnsafeFileSystemRepresentation { fileSystemPath in
let result = data.withUnsafeBytes {
setxattr(fileSystemPath, name, $0.baseAddress, data.count, 0, 0)
}
guard result >= 0 else { throw URL.posixError(errno) }
}
}
/// Remove extended attribute.
func removeExtendedAttribute(forName name: String) throws {
try self.withUnsafeFileSystemRepresentation { fileSystemPath in
let result = removexattr(fileSystemPath, name, 0)
guard result >= 0 else { throw URL.posixError(errno) }
}
}
/// Get list of all extended attributes.
func listExtendedAttributes() throws -> [String] {
let list = try self.withUnsafeFileSystemRepresentation { fileSystemPath -> [String] in
let length = listxattr(fileSystemPath, nil, 0, 0)
guard length >= 0 else { throw URL.posixError(errno) }
// Create buffer with required size:
var namebuf = Array<CChar>(repeating: 0, count: length)
// Retrieve attribute list:
let result = listxattr(fileSystemPath, &namebuf, namebuf.count, 0)
guard result >= 0 else { throw URL.posixError(errno) }
// Extract attribute names:
let list = namebuf.split(separator: 0).compactMap {
$0.withUnsafeBufferPointer {
$0.withMemoryRebound(to: UInt8.self) {
String(bytes: $0, encoding: .utf8)
}
}
}
return list
}
return list
}
/// Helper function to create an NSError from a Unix errno.
private static func posixError(_ err: Int32) -> NSError {
return NSError(domain: NSPOSIXErrorDomain, code: Int(err),
userInfo: [NSLocalizedDescriptionKey: String(cString: strerror(err))])
}
}
Run Code Online (Sandbox Code Playgroud)
用法示例:
let fileURL = URL(fileURLWithPath: "/path/to/file")
let attr1 = "com.myCompany.myAttribute"
let attr2 = "com.myCompany.otherAttribute"
let data1 = Data([1, 2, 3, 4])
let data2 = Data([5, 6, 7, 8, 9])
do {
// Set attributes:
try fileURL.setExtendedAttribute(data: data1, forName: attr1)
try fileURL.setExtendedAttribute(data: data2, forName: attr2)
// List attributes:
let list = try fileURL.listExtendedAttributes()
print(list)
// ["com.myCompany.myAttribute", "com.myCompany.otherAttribute", "other"]
let data1a = try fileURL.extendedAttribute(forName: attr1)
print(data1a as NSData)
// <01020304>
// Remove attributes
for attr in list {
try fileURL.removeExtendedAttribute(forName: attr)
}
} catch let error {
print(error.localizedDescription)
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3347 次 |
| 最近记录: |