2012-06-19 13 views
26

Tôi có tệp nhật ký mà tôi đang cố gắng nối dữ liệu vào cuối. Tôi có một biến NSMutableStringtextToWrite, và tôi đang làm như sau:Nối vào cuối tệp bằng NSMutableString

[textToWrite writeToFile:filepath atomically:YES 
            encoding: NSUnicodeStringEncoding error:&err]; 

Tuy nhiên, khi tôi làm điều này tất cả các văn bản bên trong các tập tin được thay thế bằng văn bản trong textToWrite. Làm thế nào tôi có thể thêm vào cuối của tập tin? (Hoặc thậm chí tốt hơn, làm thế nào tôi có thể thêm vào cuối của tập tin trên một dòng mới?)

+0

Tôi đoán rằng 'NSLog' sẽ không làm việc theo cách bạn muốn? – zneak

+0

FYI, không có phương pháp nào trên 'NSString' /' NSMutableString' sẽ cho phép bạn nối nó vào một tệp. Có một ví dụ [ở đây] (http://lists.apple.com/archives/cocoa-dev/2002/Aug/msg00754.html) mặc dù. – zneak

Trả lời

48

Tôi đoán bạn có thể làm một vài điều:

NSFileHandle *fileHandle = [NSFileHandle fileHandleForWritingAtPath:aPath]; 
[fileHandle seekToEndOfFile]; 
[fileHandle writeData:[textToWrite dataUsingEncoding:NSUTF8StringEncoding]]; 
[fileHandle closeFile]; 

Lưu ý rằng điều này sẽ nối NSData để bạn tệp - KHÔNG phải là NSString. Lưu ý rằng nếu bạn sử dụng NSFileHandle, bạn phải chắc chắn rằng tập tin tồn tại trước khi tay. fileHandleForWritingAtPath sẽ trả về 0 nếu không có tệp nào tồn tại ở đường dẫn. Xem số NSFileHandle class reference.

Hoặc bạn có thể làm:

NSString *contents = [NSString stringWithContentsOfFile:filepath]; 
contents = [contents stringByAppendingString:textToWrite]; 
[contents writeToFile:filepath atomically:YES encoding: NSUnicodeStringEncoding error:&err]; 

tôi tin rằng phương pháp đầu tiên sẽ là hiệu quả nhất, kể từ khi tiếp cận thứ hai liên quan đến việc đọc các nội dung của tập tin vào một NSString trước khi viết nội dung mới để các tập tin. Tuy nhiên, nếu bạn không muốn tệp của mình chứa NSData và muốn giữ văn bản đó, tùy chọn thứ hai sẽ phù hợp hơn với bạn.

[Cập nhật] Kể từ stringWithContentsOfFile là deprecated bạn có thể thay đổi cách tiếp cận thứ hai:

NSError* error = nil; 
NSString* contents = [NSString stringWithContentsOfFile:filepath 
               encoding:NSUTF8StringEncoding 
                error:&error]; 
if(error) { // If error object was instantiated, handle it. 
    NSLog(@"ERROR while loading from file: %@", error); 
    // … 
} 
[contents writeToFile:filepath atomically:YES 
           encoding:NSUnicodeStringEncoding 
            error:&err]; 

See question on stackoverflow

+0

Vì vậy, tôi đã làm gợi ý đầu tiên của bạn, và trong khi nó hoạt động, tôi có lỗi này thực sự kỳ lạ mà tất cả mọi thứ tôi nối thêm xuất hiện như là ký tự Trung Quốc! (mặc dù tất cả dữ liệu tôi viết cho tệp là bằng tiếng Anh và trước đó, khi nó thay thế văn bản, nó hiển thị dưới dạng tiếng Anh) –

+0

Tôi đã chỉnh sửa phản hồi của mình ... nó đang thêm NSData vào tệp của bạn, không rõ ràng bản văn. Nếu bạn muốn giữ cho tệp của mình ở dạng văn bản thuần túy, bạn nên sử dụng phương thức thứ hai. –

23

Ban đầu tôi nghĩ rằng việc sử dụng các phương pháp FileHandler trong câu trả lời chấp nhận rằng tôi đã đi để có được một loạt các giá trị dữ liệu hex được ghi vào tệp của tôi, nhưng tôi có văn bản có thể đọc được tất cả những gì tôi cần. Vì vậy, dựa trên câu trả lời được chấp nhận, đây là những gì tôi đã đưa ra:

-(void) writeToLogFile:(NSString*)content{ 
    content = [NSString stringWithFormat:@"%@\n",content]; 

    //get the documents directory: 
    NSString *documentsDirectory = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"]; 
    NSString *fileName = [documentsDirectory stringByAppendingPathComponent:@"hydraLog.txt"]; 

    NSFileHandle *fileHandle = [NSFileHandle fileHandleForWritingAtPath:fileName]; 
    if (fileHandle){ 
     [fileHandle seekToEndOfFile]; 
     [fileHandle writeData:[content dataUsingEncoding:NSUTF8StringEncoding]]; 
     [fileHandle closeFile]; 
    } 
    else{ 
     [content writeToFile:fileName 
        atomically:NO 
        encoding:NSStringEncodingConversionAllowLossy 
         error:nil]; 
    } 
} 

Bằng cách này nếu tệp chưa tồn tại, bạn tạo nó. Nếu nó đã tồn tại thì bạn chỉ phụ thêm vào nó. Ngoài ra, nếu bạn đi vào plist và thêm một khóa dưới danh sách thuộc tính thông tin UIFileSharingEnabled và đặt giá trị thành true thì người dùng có thể đồng bộ với máy tính của họ và xem tệp nhật ký thông qua iTunes.

+0

Có lý do nào khi tạo tệp mới mà bạn đang sử dụng mã hóa khác với khi bạn thêm tệp không? – huggie

+0

Không, tôi thậm chí còn không nhận ra điều đó. –

+1

Cách sạch hơn để xây dựng đường dẫn đó là sử dụng '[documentsDirectory stringByAppendingPathComponent: @" hydraLog.txt "]' –

1

Và đây là một (hơi thông qua) phiên bản Swift của Chase Roberts' solution:

static func writeToFile(content: String, fileName: String = "log.txt") { 
    let contentWithNewLine = content+"\n" 
    let filePath = NSHomeDirectory() + "/Documents/" + fileName 
    let fileHandle = NSFileHandle(forWritingAtPath: filePath) 
    if (fileHandle != nil) { 
     fileHandle?.seekToEndOfFile() 
     fileHandle?.writeData(contentWithNewLine.dataUsingEncoding(NSUTF8StringEncoding)!) 
    } 
    else { 
     do { 
      try contentWithNewLine.writeToFile(filePath, atomically: true, encoding: NSUTF8StringEncoding) 
     } catch { 
      print("Error while creating \(filePath)") 
     } 
    } 
}