编写扩展文件属性 swift 示例

Posted

技术标签:

【中文标题】编写扩展文件属性 swift 示例【英文标题】:Write extend file attributes swift example 【发布时间】:2016-07-13 05:19:12 【问题描述】:

我正在寻找一种快速为文件添加扩展文件属性的解决方案。我检查了这个链接Write extended file attributes,但解决方案在目标 c 中,我需要一个快速的解决方案。

【问题讨论】:

这在***.com/a/40314367/1749551中有详细讨论 【参考方案1】:

这是 Swift 5 中可能的实现,作为 URL 的扩展, 具有获取、设置、列出和删除扩展属性的方法 一份文件。 (Swift 2、3、4 的代码可以在编辑历史中找到。)

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))])
    

示例用法:

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)

【讨论】:

@prabhu:您以什么格式导出和邮寄文件?您必须选择一种保留扩展属性的格式(如果存在这种格式)。 要修复 Swift 5 中的“withUnsafeMutableBytes 已弃用”警告,请将 $0 更改为 $0.baseAddress @MariánČerný:感谢您的通知,我已经更新了 Swift 5 的代码。 @ayaio:我最近更新了 Swift 5 的代码,Swift 4 版本在 edit history 我使用这个脚本来获取文件(或文件夹)的所有标签的列表,它运行良好。示例:“let fileURL = URL(fileURLWithPath: "/Volumes/testVolume", isDirectory: true)" AND : "let attr1 = "com.apple.metadata:_kMDItemUserTags"。之后,您需要将结果转换为utf8 使其可读:“let resultatdata1a = (String(decoding: data1a, as: UTF8.self))”。我使用的是 swift 版本 5。我必须禁用沙箱才能允许此操作。

以上是关于编写扩展文件属性 swift 示例的主要内容,如果未能解决你的问题,请参考以下文章

《从零开始学Swift》学习笔记(Day 50)——扩展计算属性方法

如何在 Swift 中覆盖协议扩展的计算属性

如何设置扩展文件属性?

Swift 属性包装器

Swift 属性包装器

扩展中的延迟加载属性(Swift)