2009-03-24 22 views
61
NSData *data; 
data = [self fillInSomeStrangeBytes]; 

Mi pregunta ahora es cómo puedo escribir esto data de la forma más fácil para un archivo.La forma más fácil de escribir NSData en un archivo

(ya un NSURL file://localhost/Users/Coding/Library/Application%20Support/App/file.strangebytes haber)

Respuesta

94

NSData tiene un método llamado writeToURL:atomically: que hace exactamente lo que quiere hacer. Mire en the documentation for NSData para ver cómo usarlo.

+1

Tenga cuidado con los problemas de endian. –

+1

¿El origen del objeto 'NSData' es importante para este método? [En esta pregunta] (http://stackoverflow.com/questions/16150196/updating-sqlite-database-without-xml) Estoy guardando una base de datos .sqlite que descargué en un objeto 'NSData' de una URL, pero no parece guardarlo correctamente El archivo está escrito, pero cuando intento acceder a él (ya sea a través de mi aplicación o con un visor de terceros) me dice que no es una base de datos SQLite válida. ¿'WriteToURL: atómicamente:' solo funciona para guardar 'NSString's o algo así? – GeneralMike

+1

'NSData' es un contenedor para cualquier clase de datos binarios. La fuente original no debería importar. En cuanto a su pregunta, le recomiendo usar 'NSURLConnection' (o una biblioteca como' AFNetworking') sobre 'initWithContentsOfURL:'. Para pequeñas descargas, 'NSData' puede estar bien, pero no proporciona ningún control sobre la descarga. Cuando algo sale mal, esto hace que sea difícil diagnosticar el problema. – Alex

30

writeToURL:atomically: o writeToFile:atomically: si tiene un nombre de archivo en lugar de una URL.

+2

+1 para NSURL. NSURL inicia NSString cuando señala un archivo. Apple siempre recomienda NSURL para rutas de archivos en lugar de NSString. :) –

+9

No creo que haya una diferencia entre writeToURL vs writeToFile. De acuerdo con la documentación: "Dado que actualmente solo se admiten las URL de archivo: //, no existe diferencia entre este método y writeToFile: atómicamente :, excepto por el tipo del primer argumento" –

+0

¿Importa el origen del objeto 'NSData' para este método? [En esta pregunta] (http://stackoverflow.com/questions/16150196/updating-sqlite-database-without-xml) Estoy guardando una base de datos .sqlite que descargué en un objeto 'NSData' de una URL, pero no parece guardarlo correctamente El archivo está escrito, pero cuando intento acceder a él (ya sea a través de mi aplicación o con un visor de terceros) me dice que no es una base de datos SQLite válida. ¿'WriteToURL: atómicamente:' solo funciona para guardar 'NSString's o algo así? – GeneralMike

28

Observe que escribir NSData en un archivo es una operación IO que puede bloquear el hilo principal. Especialmente si el objeto de datos es grande.

Por lo tanto, se aconseja llevar a cabo esto en un subproceso en segundo plano, la forma más fácil sería utilizar GCD de la siguiente manera:

// 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]; 
}); 
+1

cómo recuperarlo? –

+0

['dataWithContentsOfFile:'] (https://developer.apple.com/documentation/foundation/nsdata/1547226-datawithcontentsoffile?language=objc) – Rob

0

También tiene writeToFile:options:error: o writeToURL:options:error: que puede reportar códigos de error en caso de que el ahorro de el NSData falló por alguna razón. Por ejemplo:

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; 
} 
Cuestiones relacionadas