【问题标题】:iOS how to store a NSDictionary or JSON in a file's xattr?iOS 如何将 NSDictionary 或 JSON 存储在文件的 xattr 中?
【发布时间】:2014-08-20 14:57:03
【问题描述】:

我正在使用 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 的指针操作?

【问题讨论】:

  • 但是为什么它需要是json格式,你是把它发回你的服务器吗?
  • 没错,当我尝试将文件转换为 NSData 时,扩展属性不会被发送过来,所以我只想获取字典并将其与 post 请求一起发送。

标签: ios objective-c json file xattr


【解决方案1】:

I found a Cocoanetics/DTFoundation that allows reading/writing arbitrary strings to 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;
}

【讨论】:

    【解决方案2】:

    将字典转换为二进制 plist 并写入 - 反之亦然 :)

    写:

    1. 创建字典
    2. 制作二进制 plist
    3. 写下来

    --

    阅读:

    1. 读取二进制plist
    2. 从中制作字典

    【讨论】:

      猜你喜欢
      • 2011-10-16
      • 2011-03-10
      • 1970-01-01
      • 1970-01-01
      • 2019-11-24
      • 2013-01-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多