web-dev-qa-db-ja.com

NSMutableStringを使用してファイルの末尾に追加する

末尾にデータを追加しようとしているログファイルがあります。 NSMutableStringtextToWrite変数があり、次のことを行っています。

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

ただし、これを行うと、ファイル内のすべてのテキストがtextToWriteのテキストに置き換えられます。代わりにファイルの最後に追加するにはどうすればよいですか? (さらに良いことに、ファイルの最後に新しい行を追加するにはどうすればよいですか?)

31
Julian Coltea

いくつかのことができると思います。

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

NSDataではなくNSDataがファイルに追加されることに注意してください。 NSFileHandleを使用する場合は、事前にファイルが存在することを確認する必要があることに注意してください。パスにファイルが存在しない場合、fileHandleForWritingAtPathはnilを返します。 NSFileHandleクラスリファレンス を参照してください。

またはあなたがすることができます:

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

2番目のアプローチでは、ファイルに新しいコンテンツを書き込む前に、ファイルのコンテンツをNSStringに読み込むため、最初のアプローチが最も効率的だと思います。ただし、ファイルにNSDataを含めたくない場合、テキストを保持したい場合は、2番目のオプションの方が適しています。

[更新]stringWithContentsOfFileは 非推奨 であるため、2番目のアプローチを変更できます。

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

stackoverflowに関する質問を参照

57

最初は、受け入れられた回答でFileHandlerメソッドを使用して、大量の16進データ値をファイルに書き込むと思っていましたが、必要なのは読み取り可能なテキストです。受け入れられた答えに基づいて、これは私が思いついたものです:

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

この方法では、ファイルがまだ存在しない場合は作成します。既に存在する場合は、追加するだけです。また、plistに移動して、情報プロパティリストUIFileSharingEnabledの下にキーを追加し、値をtrueに設定すると、ユーザーはコンピューターと同期し、iTunes経由でログファイルを表示できます。

29
Chase Roberts

そして、これは(少し採用された)Swift 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)")
        }
    }
}
1
Michael Dorner