写扩展文件属性swift示例 [英] Write extend file attributes swift example

查看:153
本文介绍了写扩展文件属性swift示例的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在寻找一种在swift中为文件添加扩展文件属性的解决方案。我查看了这个链接编写扩展文件属性,但解决方案是客观的,我需要一个迅捷的解决方案。

I am looking for a solution to add extended file attributes for a file in swift. I checked this link Write extended file attributes, but the solutions are in objective c and I need a solution for swift.

推荐答案

以下是Swift 3中可能的实现,作为 URL的扩展
,包含获取,设置,列出和删除
a文件的扩展属性的方法。 (Swift 2代码可以在下面找到。)

Here is a possible implementation in Swift 3 as an extension for URL, with methods to get, set, list, and remove extended attributes of a file. (Swift 2 code can be found below.)

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 {
                getxattr(fileSystemPath, name, $0, data.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, 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 data = Data(count: length)

            // Retrieve attribute list:
            let result = data.withUnsafeMutableBytes {
                listxattr(fileSystemPath, $0, data.count, 0)
            }
            guard result >= 0 else { throw URL.posixError(errno) }

            // Extract attribute names:
            let list = data.split(separator: 0).flatMap {
                String(data: Data($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(bytes: [1, 2, 3, 4])
let data2 = Data(bytes: [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)
}






(Swift 2的上一个答案:)

一个简单的例子:

let fileURL = NSURL(fileURLWithPath: "/path/to/file")
let attrName = "com.myCompany.myAttribute"
var attrData: [UInt8] = [1, 2, 3, 4, 5]

// Get local file system path:
var fileSystemPath = [Int8](count: Int(MAXPATHLEN), repeatedValue: 0)
guard fileURL.getFileSystemRepresentation(&fileSystemPath, maxLength: fileSystemPath.count) else {
    fatalError("Invalid file URL")
}

// Set extended attribute (returns 0 on success):
guard setxattr(&fileSystemPath, attrName, &attrData, attrData.count, 0, 0) == 0 else {
    perror("setxattr") // prints error message of last system call
    fatalError()
}

验证结果命令行:


$ xattr -px com.myCompany.myAttribute /path/to/file 
01 02 03 04 05

以下是如何获取和设置文件属性,实现
作为 NSURL的扩展方法

And here is how you could get and set file attributes, implemented as extension methods of NSURL:

extension NSURL {
    // Get extended attribute. Returns `nil` on failure.
    func extendedAttribute(forName name: String) -> [UInt8]? {
        // Get local file system path:
        var fileSystemPath = [Int8](count: Int(MAXPATHLEN), repeatedValue: 0)
        guard self.getFileSystemRepresentation(&fileSystemPath, maxLength: fileSystemPath.count) else {
            return nil
        }
        // Determine attribute size:
        let length = getxattr(fileSystemPath, name, nil, 0, 0, 0)
        guard length >= 0 else { return nil }
        // Create buffer with required size:
        var data = [UInt8](count: length, repeatedValue: 0)
        // Retrieve attribute:
        let result = getxattr(fileSystemPath, name, &data, data.count, 0, 0)
        guard result >= 0 else { return nil }
        return data
    }

    // Set extended attribute. Returns `true` on success and `false` on failure.
    func setExtendedAttribute(data: [UInt8], forName name: String) -> Bool {
        // Get local file system path:
        var fileSystemPath = [Int8](count: Int(MAXPATHLEN), repeatedValue: 0)
        guard self.getFileSystemRepresentation(&fileSystemPath, maxLength: fileSystemPath.count) else {
            return false
        }
        // Set attribute:
        let result = data.withUnsafeBufferPointer {
            setxattr(fileSystemPath, name, $0.baseAddress, data.count, 0, 0)
        }
        return result == 0
    }

    // Remove extended attribute. Returns `true` on success and `false` on failure.
    func removeExtendedAttribute(forName name: String) -> Bool {
        // Get local file system path:
        var fileSystemPath = [Int8](count: Int(MAXPATHLEN), repeatedValue: 0)
        guard self.getFileSystemRepresentation(&fileSystemPath, maxLength: fileSystemPath.count) else {
            return false
        }
        // Remove attribute:
        let result = removexattr(fileSystemPath, name, 0)
        return result == 0
    }
}

用法示例:

let fileURL = NSURL(fileURLWithPath: "/path/to/file")
let attrName = "com.myCompany.myAttribute"

// Set attribute:
let data1: [UInt8] = [1, 2, 3, 4]
fileURL.setExtendedAttribute(data1, forName: attrName)

// Get attribute:
if let data2 = fileURL.extendedAttribute(forName: attrName) {
    print(data2)
}

// Remove attribute:
fileURL.removeExtendedAttribute(forName: attrName)

这篇关于写扩展文件属性swift示例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆