Самый простой способ записать NSData в файл

NSData *data;
data = [self fillInSomeStrangeBytes];

Теперь мой вопрос заключается в том, как я могу записать этот data самым простым способом в файл.

(У меня уже есть NSURL file://localhost/Users/Coding/Library/Application%20Support/App/file.strangebytes)


person papr    schedule 24.03.2009    source источник


Ответы (4)


NSData имеет метод writeToURL:atomically:, который делает именно то, что вам нужно. Посмотрите документацию для NSData чтобы узнать, как его использовать.

person Alex    schedule 24.03.2009
comment
Имеет ли значение источник объекта NSData для этого метода? В этом вопросе я сохраняю базу данных .sqlite, которую я скачал, в объект NSData из URL-адрес, но, похоже, он не сохраняет его правильно. Файл записан, но когда я пытаюсь получить к нему доступ (либо через мое приложение, либо с помощью стороннего средства просмотра), он сообщает мне, что это недопустимая база данных SQLite. writeToURL:atomically: работает только для сохранения NSString или что-то в этом роде? - person GeneralMike; 25.04.2013
comment
NSData — это оболочка для любых двоичных данных. Первоисточник не должен иметь значения. Глядя на ваш вопрос, я бы рекомендовал использовать NSURLConnection (или библиотеку, например AFNetworking) вместо initWithContentsOfURL:. Для небольших загрузок может подойти NSData, но он не дает никакого контроля над загрузкой. Когда что-то идет не так, это затрудняет диагностику проблемы. - person Alex; 25.04.2013

Обратите внимание, что запись NSData в файл — это операция ввода-вывода, которая может заблокировать основной поток. Особенно, если объект данных большой.

Поэтому рекомендуется выполнять это в фоновом потоке, проще всего использовать GCD следующим образом:

// Use GCD's background queue
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
    // Generate the file path
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    NSString *dataPath = [documentsDirectory stringByAppendingPathComponent:@"yourfilename.dat"];

     // Save it into file system
    [data writeToFile:dataPath atomically:YES];
});
person Tom Susel    schedule 26.05.2014
comment
как его восстановить? - person ; 29.05.2017
comment
dataWithContentsOfFile: - person Rob; 15.02.2018

writeToURL:атомарно: или writeToFile:atomically:, если у вас есть имя файла вместо URL.

person Brian Campbell    schedule 24.03.2009
comment
+1 за NSURL. NSURL pwns NSString, когда вы указываете на файл. Apple всегда рекомендует NSURL для путей к файлам, а не NSString. :) - person ; 04.01.2011
comment
Я не думаю, что есть разница между writeToURL и writeToFile. Согласно документации: поскольку в настоящее время поддерживаются только URL-адреса file://, нет никакой разницы между этим методом и writeToFile:atomically:, за исключением типа первого аргумента. - person Ronnie Liew; 26.06.2011
comment
Имеет ли значение источник объекта NSData для этого метода? В этом вопросе я сохраняю базу данных .sqlite, которую я скачал, в объект NSData из URL-адрес, но, похоже, он не сохраняет его правильно. Файл записан, но когда я пытаюсь получить к нему доступ (либо через мое приложение, либо с помощью стороннего средства просмотра), он сообщает мне, что это недопустимая база данных SQLite. writeToURL:atomically: работает только для сохранения NSString или что-то в этом роде? - person GeneralMike; 25.04.2013

У вас также есть writeToFile:options:error: или writeToURL:options:error:, который может сообщать коды ошибок в случае сбоя сохранения NSData для любая причина. Например:

NSError *error;

NSURL *folder = [[NSFileManager defaultManager] URLForDirectory:NSApplicationSupportDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:true error:&error];
if (!folder) {
    NSLog(@"%s: %@", __FUNCTION__, error);        // handle error however you would like
    return;
}

NSURL *fileURL = [folder URLByAppendingPathComponent:filename];
BOOL success = [data writeToURL:fileURL options:NSDataWritingAtomic error:&error];
if (!success) {
    NSLog(@"%s: %@", __FUNCTION__, error);        // handle error however you would like
    return;
}
person Rob    schedule 15.02.2018