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

Câu hỏi của tôi bây giờ là cách tôi có thể viết data này một cách dễ dàng nhất vào tệp.Cách dễ nhất để viết NSData vào một tệp

(Tôi đã một NSURL file://localhost/Users/Coding/Library/Application%20Support/App/file.strangebytes)

Trả lời

94

NSData có một phương pháp gọi là writeToURL:atomically: thực hiện chính xác những gì bạn muốn làm. Tìm trong the documentation for NSData để xem cách sử dụng.

+1

Xem ra các vấn đề cuối cùng. –

+1

Nguồn của đối tượng 'NSData' có quan trọng đối với phương pháp này không? [Trong câu hỏi này] (http://stackoverflow.com/questions/16150196/updating-sqlite-database-without-xml) Tôi đang lưu một cơ sở dữ liệu .sqlite mà tôi đã tải về vào một đối tượng 'NSData' từ một URL, nhưng nó dường như không tiết kiệm chính xác. Các tập tin được viết, nhưng khi tôi cố gắng truy cập nó (hoặc thông qua ứng dụng của tôi hoặc với một người xem bên thứ 3) nó nói với tôi nó không phải là một cơ sở dữ liệu SQLite hợp lệ. Liệu 'writeToURL: nguyên tử:' chỉ làm việc để lưu 'NSString' hoặc một cái gì đó như thế? – GeneralMike

+1

'NSData' là trình bao bọc cho bất kỳ loại dữ liệu nhị phân nào. Nguồn gốc không quan trọng. Nhìn vào câu hỏi của bạn, tôi khuyên bạn nên sử dụng 'NSURLConnection' (hoặc một thư viện như' AFNetworking') trên 'initWithContentsOfURL:'. Đối với các bản tải xuống nhỏ, 'NSData' có thể tốt nhưng không cung cấp bất kỳ quyền kiểm soát nào đối với việc tải xuống. Khi xảy ra sự cố, điều này làm cho việc chẩn đoán sự cố trở nên khó khăn. – Alex

30

writeToURL:atomically: hoặc writeToFile:atomically: nếu bạn có tên tệp thay vì URL.

+2

+1 cho NSURL. NSURL pwns NSString khi bạn trỏ đến một tập tin. Apple luôn đề xuất NSURL cho đường dẫn tệp chứ không phải là NSString. :) –

+9

Tôi không nghĩ rằng có một sự khác biệt giữa writeToURL vs writeToFile. Theo tài liệu: "Vì hiện tại chỉ có file: // URL được hỗ trợ, không có sự khác biệt giữa phương thức này và writeToFile: atomically :, ngoại trừ loại đối số đầu tiên" –

+0

Liệu nguồn của đối tượng 'NSData' có quan trọng không cho phương pháp này? [Trong câu hỏi này] (http://stackoverflow.com/questions/16150196/updating-sqlite-database-without-xml) Tôi đang lưu một cơ sở dữ liệu .sqlite mà tôi đã tải về vào một đối tượng 'NSData' từ một URL, nhưng nó dường như không tiết kiệm chính xác. Các tập tin được viết, nhưng khi tôi cố gắng truy cập nó (hoặc thông qua ứng dụng của tôi hoặc với một người xem bên thứ 3) nó nói với tôi nó không phải là một cơ sở dữ liệu SQLite hợp lệ. Liệu 'writeToURL: nguyên tử:' chỉ làm việc để lưu 'NSString' hoặc một cái gì đó như thế? – GeneralMike

28

Lưu ý rằng việc viết NSData vào tệp là thao tác IO có thể chặn chuỗi chính. Đặc biệt nếu đối tượng dữ liệu lớn.

Vì vậy nó được khuyên nên thực hiện điều này trên một sợi nền, cách dễ nhất là nên sử dụng GCD như sau:

// 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ách truy xuất? –

+0

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

0

Bạn cũng có writeToFile:options:error: hay writeToURL:options:error: mà có thể báo cáo các mã lỗi trong trường hợp tiết kiệm NSData không thành công vì bất kỳ lý do gì. Ví dụ:

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; 
} 
Các vấn đề liên quan