2012-06-19 21 views
26

Mam plik dziennika, do którego próbuję dołączyć dane na końcu. Mam zmienną NSMutableStringtextToWrite i robię, co następuje:Dołączanie do końca pliku z NSMutableString

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

Jednak, gdy robię to cały tekst wewnątrz pliku zostaje zastąpiony tekstem znajdującym się w textToWrite. Jak mogę zamiast tego dołączyć do końca pliku? (Albo jeszcze lepiej, jak mogę dołączyć się do końca pliku w nowym wierszu?)

+0

myślę, że 'NSLog' nie będzie działać tak, jak chcesz? – zneak

+0

FYI, nie ma metody na 'NSString' /' NSMutableString', która pozwoli ci dołączyć ją do pliku. Istnieje jednak przykład [tutaj] (http://lists.apple.com/archives/cocoa-dev/2002/Aug/msg00754.html). – zneak

Odpowiedz

48

Myślę, że można zrobić kilka rzeczy:

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

Zauważ, że to doda NSData do listy plik - NIE NSString. Zauważ, że jeśli używasz NSFileHandle, musisz upewnić się, że plik istnieje przed ręką. fileHandleForWritingAtPath zwróci zero, jeśli nie istnieje plik na ścieżce. Zobacz NSFileHandle class reference.

Albo można zrobić:

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

Uważam, że pierwsze podejście byłoby najbardziej efektywne, ponieważ Drugie podejście polega na odczytanie zawartości pliku do NSString przed zapisaniem nowych zawartość do pliku. Ale jeśli nie chcesz, aby twój plik zawierał NSData i wolał zachować tekst, druga opcja będzie dla ciebie bardziej odpowiednia.

[Aktualizacja] Od stringWithContentsOfFile jest deprecated można zmodyfikować drugie podejście:

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

Zrobiłem więc twoją pierwszą sugestię i chociaż działa, mam ten naprawdę dziwny błąd, że wszystko, co dodaję, pojawia się jako chińskie postacie! (chociaż wszystkie dane, które piszę do pliku, są w języku angielskim, a wcześniej, kiedy zastępował tekst, pojawił się jako angielski) –

+0

Edytowałem moją odpowiedź ... to jest dołączanie NSData do pliku, nie jasne tekst. Jeśli chcesz zachować swój plik jako zwykły tekst, powinieneś użyć drugiej metody. –

23

Początkowo myślałem, że stosując metodę FileHandler w przyjętym odpowiedź że ja jechałem dostać szereg wartości danych szesnastkowych zapisanych w moim pliku, ale mam czytelny tekst, który jest wszystkim, czego potrzebuję. Tak więc opierając się na zaakceptowanej odpowiedzi, to właśnie wymyśliłem:

-(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]; 
    } 
} 

W ten sposób, jeśli plik jeszcze nie istnieje, utworzysz go. Jeśli już istnieje, to tylko do niego dołączasz. Ponadto, jeśli przejdziesz do pliku plist i dodasz klucz pod listą właściwości informacji UIFileSharingEnabled i ustawisz wartość na true, wówczas użytkownik może zsynchronizować się ze swoim komputerem i zobaczyć plik dziennika za pośrednictwem iTunes.

+0

Czy istnieje powód, dla którego podczas tworzenia nowego pliku używasz innego kodowania niż podczas dołączania do pliku? – huggie

+0

Nie, nawet tego nie zauważyłem. –

+1

Czystszym sposobem zbudowania tej ścieżki jest użycie '[documentsDirectory stringByAppendingPathComponent: @" hydraLog.txt "]' –

1

I tu jest (nieco przyjęty) Swift wersja 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)") 
     } 
    } 
}