Szukam rozwiązania, aby dodać rozszerzone atrybuty pliku dla pliku w trybie szybkiego. Sprawdziłem ten link Write extended file attributes, ale rozwiązania są obiektywne c i potrzebuję rozwiązania na szybkie.Napisz rozszerzenie atrybutów plików swift example
Odpowiedz
Oto możliwe wdrożenie w Swift 3 jako rozszerzenie dla URL
, z metod, aby uzyskać, zestaw, listy i usunąć rozszerzone atrybuty akta. (Swift i kod 2 można znaleźć poniżej.)
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))])
}
}
Przykład użycia:
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)
}
(poprzedniej odpowiedzi na szybkie 2 :)
prostym przykładzie:
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()
}
Sprawdź wynik w wierszu poleceń:
$ xattr -px com.myCompany.myAttribute /path/to/file 01 02 03 04 05
A oto w jaki sposób można pobrać i ustawić atrybuty pliku, realizowany jako metod rozszerzających 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
}
}
Przykład użycia:
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)
Rozumiem, że prosiłeś o rozwiązanie w Swift. Jednak niektórzy ludzie mogą mieć hybrydowy projekt Swift/ObjC lub być gotowym na taki projekt. W moim przypadku znacznie łatwiej było użyć Objective-C do tego jednego zadania.
#import <Foundation/Foundation.h>
@interface TagSetter: NSObject
+ (BOOL)setTags:(NSArray *)tags onURL:(NSURL *)url;
@end
@implementation TagSetter
+ (BOOL)setTags:(NSArray *)tags onURL:(NSURL *)url
{
NSError *error;
BOOL returnValue = [url setResourceValue:tags forKey:NSURLTagNamesKey error:&error];
if (!returnValue) {
NSLog(@"ERROR: Failed setting tags '%@' on URL '%@': %@", tags, url, error);
}
return returnValue;
}
@end
Kod ten jest przystosowany od tag(1) command line tool przez jdberry na GitHub. Potem następuje zgodnie z instrukcjami dla using ObjC in Swift i dodaje plik .m wyżej nagłówku pomostowego:
#import "TagSetter.m"
W końcu wszystko, co mam zrobić w kodzie SWIFT:
TagSetter.setTags(tagNames, on:url)
Jeśli chcesz odpowiedzieć na niepowodzenie, możesz.
To od Ciebie zależy, czy to podejście okaże się proste, czy lekko hacky, czy przerażająca przesada. Ale na pewno działa i daje tylko jedną linię Swift.
- 1. Rozszerzenie Simple Swift Array
- 2. jBullet example
- 3. Swift przechowywania rozszerzenie dla protokołów
- 4. Rozszerzenie zagnieżdżonego typu w Swift
- 5. Lokalizacja plików przy użyciu tagu @example z roxygen2
- 6. Napisz cv :: Mat do plików binarnych?
- 7. proste C++ hash_set example
- 8. System.Net.FtpWebRequest GetDateTimestamp example
- 9. Erlang mysql example
- 10. Disruptor helloworld example
- 11. Rozszerzenie zmiennych w zawartości plików
- 12. Rozszerzenie dużych plików dla git
- 13. Rozszerzenie Chrome do systemu plików
- 14. Swift - Skojarzona wartość lub rozszerzenie dla Enum
- 15. Swift rozszerzenie protokołu dokonać obserwator Powiadomienie
- 16. Rozszerzenie Swift "Nie znaleziono definicji metody"
- 17. React Native - Headless JS example
- 18. spring initBinder i webbindinginitializer example
- 19. Angularjs ng-animate move example?
- 20. Jak korzystać z rozszerzonych atrybutów plików w systemie plików NFS?
- 21. Pobieranie atrybutów plików z systemu Windows cmd
- 22. uzyskiwanie atrybutów twórcy plików/właściciela w Javie
- 23. Pobieranie wielu plików i zip - rozszerzenie Chrome
- 24. Jak zmienić rozszerzenie wielu plików w katalogu?
- 25. Dlaczego Android aapt usuwa rozszerzenie plików .gz?
- 26. Preferowane (lub najczęstsze) rozszerzenie plików pikle?
- 27. Napisz duży plik
- 28. Jak przekazać wiele atrybutów do dyrektywy atrybutów Angular.js?
- 29. Napisz metodę rozszerzania Rx "RetryAfter"
- 30. java - napisz dwa pliki atomicznie
Dzięki za odpowiedź. Po prostu skopiowałem twój kod i uruchomiłem aplikację. Nie wydrukowano żadnych błędów, ale nie mogłem potwierdzić zestawu atrybutów z wiersza poleceń. Otrzymałem komunikat "Brak takiego xattr: com.myCompany.myAttribute" – prabhu
@prabhu: Czy dwukrotnie sprawdziłeś, czy nazwa atrybutu w kodzie jest taka sama jak nazwa atrybutu w linii poleceń? Za pomocą 'xattr/path/to/file' możesz wyświetlić listę wszystkich istniejących atrybutów pliku. - Udało mi się, przetestowałem kod przed wysłaniem :) –
Tak, to jest tak samo jak w twoim przykładzie. Nie jestem pewien, czy czegoś brakuje. Ale po prostu kopiuję wkleiłem wszystko, co napisałeś. Bez zmian – prabhu