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

Moje pytanie brzmi teraz, jak mogę napisać tę data w najprostszy sposób do pliku.Najprostszy sposób na zapisanie NSData do pliku

(mam już w bibliotece NSURL file://localhost/Users/Coding/Library/Application%20Support/App/file.strangebytes)

Odpowiedz

94

NSData ma metodę zwaną writeToURL:atomically: że robi dokładnie to, co chcesz zrobić. Sprawdź w the documentation for NSData, jak z niego korzystać.

+1

Uważaj na problemy endian. –

+1

Czy źródło obiektu 'NSData' ma znaczenie dla tej metody? [W tym pytaniu] (http://stackoverflow.com/questions/16150196/updating-sqlite-database-without-xml) Zapisuję bazę danych .sqlite, którą pobrałem do obiektu 'NSData' z adresu URL, ale wygląda na to, że nie zapisuje go poprawnie. Plik jest zapisany, ale kiedy próbuję uzyskać do niego dostęp (za pośrednictwem mojej aplikacji lub przeglądarki innej firmy), mówi mi, że nie jest to poprawna baza danych SQLite. Czy 'writeToURL: atomically:' działa tylko dla zapisu 'NSString's czy coś w tym stylu? – GeneralMike

+1

'NSData' jest opakowaniem dla dowolnego rodzaju danych binarnych. Oryginalne źródło nie powinno mieć znaczenia. Patrząc na twoje pytanie, polecam używanie 'NSURLConnection' (lub biblioteki takiej jak' AFNetworking') zamiast 'initWithContentsOfURL:'. W przypadku małych pobrań, 'NSData' może być w porządku, ale nie zapewnia żadnej kontroli nad pobieraniem. Gdy coś pójdzie nie tak, trudno będzie zdiagnozować problem. – Alex

30

writeToURL:atomically: lub writeToFile:atomically: jeśli masz nazwę pliku zamiast adresu URL.

+2

+1 dla NSURL. NSURL pwns NSString po wskazaniu pliku. Apple zawsze zaleca NSURL dla ścieżek plików zamiast NSString. :) –

+9

Nie sądzę, że istnieje różnica między writeToURL a writeToFile. Zgodnie z dokumentacją: "Ponieważ obecnie obsługiwane są tylko pliki: // URL, nie ma różnicy między tą metodą a writeToFile: atomically :, z wyjątkiem typu pierwszego argumentu" –

+0

Czy źródło obiektu 'NSData' ma znaczenie dla tej metody? [W tym pytaniu] (http://stackoverflow.com/questions/16150196/updating-sqlite-database-without-xml) Zapisuję bazę danych .sqlite, którą pobrałem do obiektu 'NSData' z adresu URL, ale wygląda na to, że nie zapisuje go poprawnie. Plik jest zapisany, ale kiedy próbuję uzyskać do niego dostęp (za pośrednictwem mojej aplikacji lub przeglądarki innej firmy), mówi mi, że nie jest to poprawna baza danych SQLite. Czy 'writeToURL: atomically:' działa tylko dla zapisu 'NSString's czy coś w tym stylu? – GeneralMike

28

Zauważ, że wpisanie NSData do pliku jest operacją we/wy, która może zablokować główny wątek. Zwłaszcza, gdy obiekt danych jest duży.

Dlatego zaleca się wykonać to na wątku tła, najprostszym sposobem będzie użycie GCD następująco:

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

jak go odzyskać? –

+0

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

0

Trzeba również writeToFile:options:error: lub writeToURL:options:error: który może zgłosić kody błędów w przypadku oszczędność NSData nie powiodło się z jakiegokolwiek powodu. Na przykład:

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; 
} 
Powiązane problemy