Хранение произвольных метаданных в текстовом файле

Я пишу текстовый редактор, и мне нужно будет сохранить несколько фрагментов информации (как правило, всего несколько строк; хранилище не должно быть особенно долговечным) с каждым файлом, который сохраняет приложение (без того, чтобы быть частью текстового файла, поскольку другие приложения могут его прочитать, и информация относится только к моему приложению).

Как бы я это сделал?


дополнительная информация: у меня настроен NSDocument, и я хотел бы просто сохранить переменную экземпляра NSString в качестве файла мета-датум. Основываясь на приведенных ниже ответах, я придумал это, которое в настоящее время глючит и вызывает сбой программы при запуске:

#import <sys/xattr.h>
@interface MyDocument : NSDocument {
  NSString *metadatum;
}

@implementation MyDocument 

- (BOOL)writeToURL:(NSURL *)url ofType:(NSString *)type error:(NSError **)err
{
  BOOL output = [super writeToURL:url ofType:type error:err];
  if(!setxattr([[url path] cStringUsingEncoding:NSUTF8StringEncoding], 
               "eu.gampleman.xattrs.style", 
               [metadatum cStringUsingEncoding:NSUTF8StringEncoding], 
               sizeof(char) * [styleName length], 0, 0)) 
  {
      NSLog(@"Write failure");
  }
  return output;
}

- (BOOL)readFromURL:(NSURL *)url ofType:(NSString *)type error:(NSError **)err {
  char *output;
  ssize_t bytes = getxattr([[url path] cStringUsingEncoding:NSUTF8StringEncoding],
                           "eu.gampleman.xattrs.style", &output, 1024, 0, 0);
  if (bytes > 0) {
    metadatum = [[NSString alloc] initWithBytes:output length:bytes 
          encoding:NSUTF8StringEncoding]; // <- crashes here with "EXC_BAD_ACCESS"
  }
  return [super readFromURL:url ofType:type error: err];
}

// ...
// fairly standard -dataOfType:error: and 
// -readFromData:ofType:error: implementations

PS: Если ваш ответ действительно хорош (с образцом кода и т. д.) Я вручу награду 100rep.

2 ответов


использовать дополнительные атрибуты. См.setxattr().

вот пример вызова для записи строки:

NSData* encodedString = [theString dataUsingEncoding:NSUTF8StringEncoding];
int rc = setxattr("/path/to/your/file", "com.yourcompany.yourapp.yourattributename", [encodedString bytes], [encodedString length], 0, 0);
if (rc)
    /* handle error */;

читать строку:

ssize_t len = getxattr("/path/to/your/file", "com.yourcompany.yourapp.yourattributename", NULL, 0, 0, 0);
if (len < 0)
    /* handle error */;
NSMutableData* data = [NSMutableData dataWithLength:len];
len = getxattr("/path/to/your/file", "com.yourcompany.yourapp.yourattributename", [data mutableBytes], len, 0, 0);
NSString* string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];

PS: разве вам не нужно установить награду на вопрос, прежде чем он ответит?


есть несколько мест для хранения такой информации на Mac. Самое простое, конечно, это хранить его в собственной отдельной базе метаданных. Конечно, есть проблемы, если файл перемещается. Однако начиная с 10.6 вы можете использовать закладки для решения этой проблемы. Закладка (см. NSURL) позволяет сохранить ссылку на файл, даже если он перемещается (даже при перезапуске приложения). До 10.6 был менеджер псевдонимов, но он не мог создавать новые псевдонимы; просто читайте те, которые создал Finder.

следующим распространенным решением является создание файлов метаданных. Так что если у меня есть foo.txt, затем вы создаете брата .foo.txt.metadata для хранения дополнительной информации. Несколько компромиссов, если файлы можно перемещать.

Далее идет Spotlight, который можно использовать для прикрепления произвольной информации к файлам. Фактическим инструментом здесь является xattr (см. man-страницы для setxattr и ее родственников). Они в основном поглощают несколько вещей, которые раньше делали с ресурсом Вилки (за исключением того, что xattr должен быть только метаданными).