Конвертировать вывод mdls в NSDictionary

Запуск инструмента метаданных BSD в Терминале для файла CSV ($ mdls foo.csv) будет производить вывод, как это:

kMDItemContentCreationDate     = 2014-08-27 15:28:16 +0000
kMDItemContentModificationDate = 2014-08-27 15:28:16 +0000
kMDItemContentType             = "public.comma-separated-values-text"
kMDItemContentTypeTree         = (
    "public.comma-separated-values-text",
    "public.delimited-values-text",
    "public.text",
    "public.data",
    "public.item",
    "public.content"
)
kMDItemDateAdded               = 2014-08-27 15:28:16 +0000
kMDItemDisplayName             = "foo.csv"
kMDItemFSContentChangeDate     = 2014-08-27 15:28:16 +0000
kMDItemFSCreationDate          = 2014-08-27 15:28:16 +0000
kMDItemFSCreatorCode           = ""
kMDItemFSFinderFlags           = 0
kMDItemFSHasCustomIcon         = (null)
kMDItemFSInvisible             = 0
kMDItemFSIsExtensionHidden     = 0
kMDItemFSIsStationery          = (null)
kMDItemFSLabel                 = 0
kMDItemFSName                  = "foo.csv"
kMDItemFSNodeCount             = (null)
kMDItemFSOwnerGroupID          = 20
kMDItemFSOwnerUserID           = 501
kMDItemFSSize                  = 962
kMDItemFSTypeCode              = ""
kMDItemKind                    = "comma-separated values"
kMDItemLogicalSize             = 962
kMDItemPhysicalSize            = 4096

Я хотел бы захватить этот вывод в коде и преобразовать его в NSDictionary.

...

//
// run mdls on file
//

NSURL *url = @"path/to/file/foo.csv";

NSPipe *pipe = [NSPipe pipe];
NSFileHandle *file = pipe.fileHandleForReading;

NSTask *task = [[NSTask alloc] init];
task.launchPath = @"/usr/bin/mdls";
task.arguments = @[url];
task.standardOutput = pipe;

[task launch];

NSData *data = [file readDataToEndOfFile];
NSString *content = [[NSString alloc] initWithData: data encoding: NSUTF8StringEncoding];

//
// populate dictionary
//
NSDictionary *dictionary = [NSDictionary alloc] init];

// pseudo-code
NSArray *rows = split string on \n to create array of rows;

for each row {

  if (row doesn't end with a '(' or start with a ')') { 
    split rows on \= to create key and value;
    add key and value to dictionary;
  }

  else if (row starts with a '(') {
    add key to dictionary; 
    create NSArray; 
    set marker on;
  }

  else if (row ends with a ')') {
    add value to dictionary;
    set marker off;
  }

  if (marker) {
    add value to array;
  }
}

//

Есть ли более элегантный подход?

1 ответ

Решение

Есть ли более элегантный подход?

Мальчик, есть ли когда-нибудь!;)

Почему вы пытаетесь разобрать вывод mdls Команда, когда эта команда построена на API, вы можете использовать сами?

MDItemRef item = MDItemCreateWithURL(NULL, (__bridge CFURLRef)url);
CFArrayRef names = MDItemCopyAttributeNames(item);
NSDictionary* dictionary = CFBridgingRelease(MDItemCopyAttributes(item, names));
CFRelease(names);
CFRelease(item);

(И только потому, что вы спросили о разборе выходных данных mdlsЯ укажу, что у него есть -plist вариант. Если вы используете его и укажите - как файл, вы можете прочитать plist из его стандартного вывода и проанализировать его, используя NSPropertyListSerialization.)

Другие вопросы по тегам