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

La mia domanda è ora come posso scrivere questo data il modo più semplice per un file.Il modo più semplice di scrivere NSData in un file

(ho già un NSURL file://localhost/Users/Coding/Library/Application%20Support/App/file.strangebytes)

risposta

94

NSData ha un metodo chiamato writeToURL:atomically: che fa esattamente ciò che si vuole fare. Cerca in the documentation for NSData per vedere come usarlo.

+1

Attenzione per problemi di endian. –

+1

La sorgente dell'oggetto 'NSData' è importante per questo metodo? [In questa domanda] (http://stackoverflow.com/questions/16150196/updating-sqlite-database-without-xml) Sto salvando un database .sqlite che ho scaricato in un oggetto 'NSData' da un URL, ma sembra che non lo stia salvando correttamente. Il file è scritto, ma quando provo ad accedervi (tramite la mia app o con un visualizzatore di terze parti) mi dice che non è un database SQLite valido. 'WriteToURL: atomically:' funziona solo per salvare 'NSString's o qualcosa del genere? – GeneralMike

+1

'NSData' è un wrapper per qualsiasi tipo di dati binari. La fonte originale non dovrebbe importare. Osservando la tua domanda, ti consiglio di usare 'NSURLConnection' (o una libreria come' AFNetworking') su 'initWithContentsOfURL:'. Per piccoli download, 'NSData' può andare bene, ma non fornisce alcun controllo sul download. Quando qualcosa va storto, questo rende difficile diagnosticare il problema. – Alex

30

writeToURL:atomically: o writeToFile:atomically: se si ha un nome file invece di un URL.

+2

+1 per NSURL. NSURL pwns NSString quando si punta a un file. Apple consiglia sempre NSURL per i percorsi dei file anziché NSString. :) –

+9

Non penso che ci sia una differenza tra writeToURL vs writeToFile. Secondo la documentazione: "Poiché al momento sono supportati solo file: // URL, non vi è alcuna differenza tra questo metodo e writeToFile: atomically :, ad eccezione del tipo del primo argomento" –

+0

Il sorgente dell'oggetto 'NSData' per questo metodo? [In questa domanda] (http://stackoverflow.com/questions/16150196/updating-sqlite-database-without-xml) Sto salvando un database .sqlite che ho scaricato in un oggetto 'NSData' da un URL, ma sembra che non lo stia salvando correttamente. Il file è scritto, ma quando provo ad accedervi (tramite la mia app o con un visualizzatore di terze parti) mi dice che non è un database SQLite valido. 'WriteToURL: atomically:' funziona solo per salvare 'NSString's o qualcosa del genere? – GeneralMike

28

Si noti che la scrittura di NSData in un file è un'operazione IO che potrebbe bloccare il thread principale. Soprattutto se l'oggetto dati è grande.

Pertanto si consiglia di eseguire questo su un thread in background, il modo più semplice sarebbe quella di utilizzare GCD come segue:

// 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

come recuperarlo? –

+0

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

0

Hai anche writeToFile:options:error: o writeToURL:options:error: che possono segnalare i codici di errore nel caso in cui il risparmio di il NSData non è riuscito per nessuna ragione. Ad esempio:

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; 
} 
Problemi correlati