ios 使用 NSMutableString 附加到文件末尾

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11106584/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 18:51:49  来源:igfitidea点击:

Appending to the end of a file with NSMutableString

objective-ciosfile-ioappendnsmutablestring

提问by Julian Coltea

I have a log file that I'm trying to append data to the end of. I have an NSMutableStringtextToWritevariable, and I am doing the following:

我有一个日志文件,我试图将数据附加到末尾。我有一个NSMutableStringtextToWrite变量,我正在执行以下操作:

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

However, when I do this all the text inside the file is replaced with the text in textToWrite. How can I instead append to the end of the file? (Or even better, how can I append to the end of the file on a new line?)

但是,当我这样做时,文件中的所有文本都将替换为 textToWrite 中的文本。我如何才能附加到文件的末尾?(或者更好的是,如何将文件的末尾追加到新行?)

回答by Michael Frederick

I guess you could do a couple of things:

我想你可以做几件事:

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

Note that this will append NSData to your file -- NOT an NSString. Note that if you use NSFileHandle, you must make sure that the file exists before hand. fileHandleForWritingAtPathwill return nil if no file exists at the path. See the NSFileHandle class reference.

请注意,这会将 NSData 附加到您的文件中——而不是 NSString。请注意,如果您使用 NSFileHandle,则必须事先确保该文件存在。fileHandleForWritingAtPath如果路径中不存在文件,则返回 nil。请参阅NSFileHandle 类参考

Or you could do:

或者你可以这样做:

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

I believe the first approach would be the most efficient, since the second approach involves reading the contents of the file into an NSString before writing the new contents to the file. But, if you do not want your file to contain NSData and prefer to keep it text, the second option will be more suitable for you.

我相信第一种方法是最有效的,因为第二种方法涉及在将新内容写入文件之前将文件的内容读入 NSString。但是,如果您不希望您的文件包含 NSData 并希望将其保留为文本,则第二个选项将更适合您。

[Update]Since stringWithContentsOfFile is deprecatedyou can modify second approach:

[更新]由于 stringWithContentsOfFile 已弃用,您可以修改第二种方法:

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

请参阅有关 stackoverflow 的问题

回答by Chase Roberts

Initially I thought that using the FileHandler method in the accepted answer that I was going to get a bunch of hex data values written to my file, but I got readable text which is all I need. So based off the accepted answer, this is what I came up with:

最初我认为在接受的答案中使用 FileHandler 方法,我会得到一堆写入我的文件的十六进制数据值,但我得到了我需要的可读文本。所以根据接受的答案,这就是我想出的:

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

This way if the file doesn't yet exist, you create it. If it already exists then you only append to it. Also, if you go into the plist and add a key under the information property list UIFileSharingEnabled and set the value to true then the user can sync with their computer and see the log file through iTunes.

这样,如果文件尚不存在,则创建它。如果它已经存在,那么你只需要附加到它。此外,如果您进入 plist 并在信息属性列表 UIFileSharingEnabled 下添加一个键并将值设置为 true,那么用户可以与他们的计算机同步并通过 iTunes 查看日志文件。

回答by Michael Dorner

And here is a (slightly adopted) Swift version of Chase Roberts' solution:

这是Chase Roberts 解决方案的(略微采用的)Swift 版本:

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)")
        }
    }
}