Как читать из папки /Library/Application Support/?

Я делаю приложение OX Cocoa и хочу иметь возможность читать и записывать текстовые файлы с помощью приложения при нажатии кнопки. Эти текстовые файлы должны быть сохранены в /Library/Application Support/AppName, но я не могу заставить свое приложение читать что-либо оттуда. Он может писать в папку, но не читать то, что он там написал, хотя я вижу файл, находящийся там, в Finder.

Вот код, который я использую для успешной записи в папку.

    NSString *text = editor.string;
    NSString *path = @"/Library/Application Support/";

    NSMutableString *mu = [[NSMutableString stringWithString:path] init];
    [mu insertString:FileName.stringValue atIndex:mu.length];
    [mu insertString:@".txt" atIndex:mu.length];

    path = [mu copy];
    [text writeToFile:path atomically:YES encoding:NSUTF8StringEncoding error:NULL];

Вот код, который я использую (и не могу) для чтения из текстовых файлов.

    NSArray *path = [[NSBundle mainBundle] pathsForResourcesOfType:@"txt" inDirectory:@"/Library/Application Support/"];
    NSString *output = @"";

    NSMutableString *mu = [[NSMutableString stringWithString:output] init];

    for (int i = 0; i < [path count]; i++) {
        NSString *text = [NSString stringWithContentsOfFile:path[i] encoding:NSUTF8StringEncoding error:NULL];
        [mu insertString:text atIndex:mu.length];
        [mu insertString:@"\n" atIndex:mu.length];
    }

    [textView setString:mu];

Любые советы о том, что я могу исправить, были бы очень полезны, я немного застрял здесь.

Изменить: используя ваш вклад, я обновил свой код следующим образом:

    NSString *fileLocation = @"~/Library/Application Support/";
    NSArray *text = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:fileLocation error:nil];
    NSString *output = @"";
    NSMutableString *mu = [[NSMutableString stringWithString:output] init];

    for (int i = 0; i < [text count]; i++) {
        [mu insertString:text[i] atIndex:mu.length];
        [mu insertString:@"\n" atIndex:mu.length];
    }
    [textView setString:mu];

Однако текст из файлов по-прежнему не появляется.


person Andrew Doig    schedule 14.02.2013    source источник


Ответы (3)


/Library/Application Support не входит в ваш комплект. Пути, которые вы получаете с помощью [[NSBundle mainBundle] pathsForResourcesOfType:…], полезны только для доступа к файлам внутри самого приложения (изображениям, звукам и т. д., которые вы включили при создании приложения).

Вы хотите использовать [[NSFileManager defaultManager] contentsOfDirectoryAtPath:path error:error] для получения списка файлов в каталоге вне вашего приложения.

У Мэтта Галлахера есть отличный пример отказоустойчивого метода определения пути к каталогу поддержки вашего приложения по адресу Какао с любовью. Я бы рекомендовал использовать его вместо жесткого кодирования пути /Library/Application Support.

NSError *error = nil;
NSArray *text = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:fileLocation error:&error];
if (!text) {
    NSLog( @"Error reading contents of application support folder at %@.\n%@", applicationSupportFolder, [error userInfo] );
}
person Tyler Bindon    schedule 14.02.2013
comment
В исходном коде для записи файлов, на которые вы указываете /Library/Application Support. Вы изменили это, чтобы оно соответствовало ~/Library/Application Support, который вы используете здесь? - person Tyler Bindon; 15.02.2013
comment
~ имеет значение? - person Andrew Doig; 15.02.2013
comment
да. ~ расширяется до /Users/*username*/Library/Application Support, без ~ он переходит в глобальную папку /Library/Application Support. - person Tyler Bindon; 15.02.2013
comment
Полезно знать, но это не работает ни с одним из них, какой из них я хотел бы использовать? - person Andrew Doig; 15.02.2013
comment
Вероятно, вам следует использовать ~. Если данные, которые вы пишете, не предназначены для совместного использования пользователями на одном компьютере. - person Tyler Bindon; 15.02.2013
comment
Вам не хватает имени программы в пути, как это выглядит. Попадают ли файлы, которые вы сейчас пишете, в папку вашего приложения? - person Tyler Bindon; 15.02.2013
comment
Я удалил последнюю часть пути для небольшой конфиденциальности, но они идут в папку, расположенную в /Library/Application Support/App Name/SubFolder. - person Andrew Doig; 15.02.2013
comment
Не беспокойся. Я бы порекомендовал вам вставить NSLog( @"%@", text ); после вызова файлового менеджера, и вы увидите, что возвращается на панели консоли Xcode. - person Tyler Bindon; 15.02.2013
comment
Это была отличная идея. Он показывает возврат текста (null), что полезно. - person Andrew Doig; 15.02.2013
comment
Итак, вам нужно выяснить, в чем ошибка. Вызов вернет ошибку в параметре ошибки, если вы передадите ее. Я добавлю пример этого в свой ответ. - person Tyler Bindon; 15.02.2013
comment
Если это поможет, я успешно читал производные данные из папки отладки, используя путь к файлу @;, но затем я безуспешно пытался читать из папки поддержки приложений. - person Andrew Doig; 15.02.2013
comment
Я ввел ваш код ошибки, и он вернул использование необъявленного идентификатора «applicationSupportFolder». Мне также пришлось изменить файловый менеджер на NSFileManager. - person Andrew Doig; 15.02.2013
comment
Прости. Я вырезал это из своего кода. applicationSupportFolder должен быть путем, и вы захотите изменить fileManager на [NSFileManager defaultManager] - person Tyler Bindon; 15.02.2013
comment
Что-то работает, дайте мне секунду, чтобы понять это. спасибо кстати - person Andrew Doig; 15.02.2013
comment
Итак, я получил ошибку, получил файл, ожидал папку или что-то в этом роде, поэтому я удалил тестовый файл .txt из конца пути, и он вывел имена файлов в папке. Это прогресс, но я хотел вывести содержимое одного файла. - person Andrew Doig; 15.02.2013
comment
Если вы знаете весь путь, вы можете отказаться от всего, что связано с NSFileManager, и поместить его прямо в stringWithContentsOfFileAtPath. Цикл вообще не нужен. Просто NSString *fileContents = [NSString stringWithContentsOfFileAtPath:path…] и [textView setString:fileContents] - person Tyler Bindon; 15.02.2013
comment
Эта строка: NSString *fileContents = [NSString stringWithContentsOfFileAtPath: кодировка fileLocation: NSUTF8StringEncoding error: NULL]; выдает ошибку «нет известного метода класса» stringWithContentsOfFileAtPath. - person Andrew Doig; 15.02.2013
comment
Прости. Часть AtPath не обязательно должна быть там. Это строкаWithContentsOfFile. - person Tyler Bindon; 15.02.2013
comment
ПОНЯТНО! Если бы я мог обнять тебя, я бы - person Andrew Doig; 15.02.2013
comment
готово, пока не могу проголосовать, но обязательно вернусь и сделаю это, когда смогу - person Andrew Doig; 15.02.2013
comment
Точнее, ~ расширяется до домашней папки. Это не обязательно /Users/$USER. - person Peter Hosey; 15.02.2013
comment
Истинный. Я рекомендовал вообще не жестко кодировать путь. - person Tyler Bindon; 16.02.2013

Большинство жестко запрограммированных путей не будут работать, если вы поместите свое приложение в песочницу. Даже если вам это сойдет с рук или вы не планируете помещать это приложение в песочницу, это плохая привычка, от которой стоит избавиться.

Кроме того, вы уверены, что хотите /Library, а не ~/Library? Первый часто недоступен для записи пользователем. Последний находится в домашнем каталоге пользователя (или в вашем контейнере в песочнице).

Чтобы получить каталог Application Support, каталог Caches или любой другой каталог, в котором вы можете создавать вещи и затем извлекать их, спросите у файлового менеджера это.

person Peter Hosey    schedule 15.02.2013

Вы пытаетесь получить путь с помощью NSBundle из основного пакета приложения. Но файла нет в комплекте, надо указать путь вручную. Вы можете жестко запрограммировать путь, где-то хранить ранее записанные пути или использовать NSFileManager для получения содержимого каталога и его анализа. Например, -[NSFileManager contentsOfDirectoryAtPath:error:].

person eofster    schedule 14.02.2013