iOS 如何在文件的 xattr 中存储 NSDictionary 或 JSON?



我正在使用setxattr命令查看iOS和Mac文件的扩展文件属性。据我所知,我可以在那里存储任意数据,最大可达128kb。

我怎么能写和读扩展属性,如果我正在处理一个字典,而不是解引用字符串指针?

到目前为止,我有这段代码,试图设置一个单一的属性。

NSString* filepath = [MyValueObject filepath]; 
const char *systemPath = [filepath fileSystemRepresentation];
const char *name = "special_value";
const char *value = "test string";
int result = setxattr(systemPath, name, &value, strlen(value), 0, 0);

如果我需要存储一小组值(比如5个键值对),我想:

  1. 创建带有我的属性的NSDictionary
  2. 将字典转换为JSON字符串
  3. 将字符串转换为字符指针
  4. 将字符串写入扩展属性
  5. 要回读属性,我会回读字符串指针
  6. 转换为NSString
  7. 转换为JSON对象
  8. 创建字典返回
  9. 从字典中检索值

这看起来是正确的方法吗?是否有一种更简单的方法来存储扩展属性中的元数据?也许有一个类别在NSObject上处理xattr的指针操作?

我找到了一个Cocoanetics/DTFoundation,它允许读取/写入任意字符串到xattr:与其他帖子一起,我能够完成我想要的-编写/恢复字典

#import "Note+ExtendedAttribute.h"
#include <sys/xattr.h>

@implementation MyFile (ExtendedAttribute)
-(NSString*)dictionaryKey
{
    return @"mydictionary";
}
-(BOOL)writeExtendedAttributeDictionary:(NSDictionary*)dictionary
{
    NSError *error;
    NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dictionary
                                                       options:0
                                                         error:&error];
    if (! jsonData) {
        return NO;
    }
    NSString* jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];

    const char *filepath = [[self filepath] fileSystemRepresentation];
    const char *key = [[self dictionaryKey] UTF8String];
    const char *value = [jsonString UTF8String];
    int result = setxattr(filepath, key, value, strlen(value), 0, 0);
    if(result != 0)
    {
        return NO;
    }
    return YES;
}
阅读:

-(NSMutableDictionary*)readExtendedAttributeDictionary
{
    const char *attrName = [[self dictionaryKey] UTF8String];
    const char *filePath = [[self filepath] fileSystemRepresentation];
    // get size of needed buffer
    int bufferLength = getxattr(filePath, attrName, NULL, 0, 0, 0);
    if(bufferLength<=0)
    {
        return nil;
    }
    // make a buffer of sufficient length
    char *buffer = malloc(bufferLength);
    // now actually get the attribute string
    getxattr(filePath, attrName, buffer, bufferLength, 0, 0);
    // convert to NSString
    NSString *retString = [[NSString alloc] initWithBytes:buffer length:bufferLength encoding:NSUTF8StringEncoding];
    // release buffer
    free(buffer);
     NSData *data = [retString dataUsingEncoding:NSUTF8StringEncoding];
    if(data == nil || data.length == 0)
    {
        return nil;
    }
    NSError *error = nil;
    id json = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
    if([json isKindOfClass:[NSDictionary class]])
    {
        return [NSMutableDictionary dictionaryWithDictionary:json];
    }
    if(error)
    {
        return nil;
    }

    return json;
}

将字典转换为二进制列表并写入——反之亦然:)

写:

  1. 创建dict
  2. 创建二进制plist

,

:

  1. 读取二进制列表
  2. 创建一个字典

最新更新