web-dev-qa-db-fra.com

Ajout à la fin d'un fichier avec NSMutableString

J'ai un fichier journal que j'essaie d'ajouter des données à la fin. J'ai une variable NSMutableStringtextToWrite et je fais ce qui suit:

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

Cependant, lorsque je fais cela, tout le texte à l'intérieur du fichier est remplacé par le texte de textToWrite. Comment puis-je ajouter à la fin du fichier? (Ou encore mieux, comment puis-je ajouter à la fin du fichier sur une nouvelle ligne?)

36
Julian Coltea

Je suppose que vous pourriez faire deux ou trois choses:

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

Notez que cela ajoutera NSData à votre fichier - PAS une NSString. Notez que si vous utilisez NSFileHandle, vous devez vous assurer que le fichier existe au préalable. fileHandleForWritingAtPath renverra nil si aucun fichier n'existe sur le chemin. Voir référence de classe NSFileHandle .

Ou vous pourriez faire:

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

Je crois que la première approche serait la plus efficace, car la deuxième approche consiste à lire le contenu du fichier dans une NSString avant d'écrire le nouveau contenu dans le fichier. Mais, si vous ne voulez pas que votre fichier contienne NSData et préférez le conserver sous forme de texte, la deuxième option vous conviendra mieux.

[Update] Puisque stringWithContentsOfFile est obsolète vous pouvez modifier la deuxième approche:

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

Voir question sur stackoverflow

61
Michael Frederick

Au début, je pensais qu'en utilisant la méthode FileHandler dans la réponse acceptée, j'allais obtenir un tas de valeurs de données hexadécimales écrites dans mon fichier, mais j'ai obtenu un texte lisible qui est tout ce dont j'ai besoin. Donc, sur la base de la réponse acceptée, voici ce que j'ai trouvé:

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

De cette façon, si le fichier n'existe pas encore, vous le créez. S'il existe déjà, vous ne pouvez que l'ajouter. De plus, si vous allez dans le plist et ajoutez une clé sous la liste des propriétés d'informations UIFileSharingEnabled et définissez la valeur sur true, l'utilisateur peut se synchroniser avec son ordinateur et voir le fichier journal via iTunes.

31
Chase Roberts

Et voici une version (légèrement adoptée) Swift version de solution de Chase Roberts :

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)")
        }
    }
}
1
Michael Dorner