将文本或数据附加到Swift中的文本文件
我已经阅读从文本文件读取和写入数据
我需要将数据(一个string)附加到我的文本文件的末尾。
一个显而易见的方法是从磁盘读取文件并将string追加到文件末尾并将其写回,但效率不高,特别是在处理大文件和经常执行时。
所以问题是“如何将string追加到文本文件的末尾,而不读取文件并将整个事件写回”?
到目前为止我有:
let dir:NSURL = NSFileManager.defaultManager().URLsForDirectory(NSSearchPathDirectory.CachesDirectory, inDomains: NSSearchPathDomainMask.UserDomainMask).last as NSURL let fileurl = dir.URLByAppendingPathComponent("log.txt") var err:NSError? // until we find a way to append stuff to files if let current_content_of_file = NSString(contentsOfURL: fileurl, encoding: NSUTF8StringEncoding, error: &err) { "\(current_content_of_file)\n\(NSDate()) -> \(object)".writeToURL(fileurl, atomically: true, encoding: NSUTF8StringEncoding, error: &err) }else { "\(NSDate()) -> \(object)".writeToURL(fileurl, atomically: true, encoding: NSUTF8StringEncoding, error: &err) } if err != nil{ println("CANNOT LOG: \(err)") }
你应该使用NSFileHandle,它可以查找文件的结尾
let dir:NSURL = NSFileManager.defaultManager().URLsForDirectory(NSSearchPathDirectory.CachesDirectory, inDomains: NSSearchPathDomainMask.UserDomainMask).last as NSURL let fileurl = dir.URLByAppendingPathComponent("log.txt") let string = "\(NSDate())\n" let data = string.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)! if NSFileManager.defaultManager().fileExistsAtPath(fileurl.path!) { var err:NSError? if let fileHandle = NSFileHandle(forWritingToURL: fileurl, error: &err) { fileHandle.seekToEndOfFile() fileHandle.writeData(data) fileHandle.closeFile() } else { println("Can't open fileHandle \(err)") } } else { var err:NSError? if !data.writeToURL(fileurl, options: .DataWritingAtomic, error: &err) { println("Can't write \(err)") } }
这里是PointZeroTwo在Swift 3.0中的答案的一个更新,有一个简单的说明 – 在操场上使用简单的文件path进行testing,但在我的实际应用程序中,我需要使用.documentDirectory(或者您select用于阅读的目录和写作 – 确保它在整个应用程序中是一致的):
extension String { func appendLineToURL(fileURL: URL) throws { try (self + "\n").appendToURL(fileURL: fileURL) } func appendToURL(fileURL: URL) throws { let data = self.data(using: String.Encoding.utf8)! try data.append(fileURL: fileURL) } } extension Data { func append(fileURL: URL) throws { if let fileHandle = FileHandle(forWritingAtPath: fileURL.path) { defer { fileHandle.closeFile() } fileHandle.seekToEndOfFile() fileHandle.write(self) } else { try write(to: fileURL, options: .atomic) } } } //test do { let dir: URL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).last! as URL let url = dir.appendingPathComponent("logFile.txt") try "Test \(Date())".appendLineToURL(fileURL: url as URL) let result = try String(contentsOf: url as URL, encoding: String.Encoding.utf8) } catch { print("Could not write to file") }
谢谢PointZeroTwo。
这里是Swift 2的一个版本,在String和NSData上使用扩展方法。
//: Playground - noun: a place where people can play import UIKit extension String { func appendLineToURL(fileURL: NSURL) throws { try self.stringByAppendingString("\n").appendToURL(fileURL) } func appendToURL(fileURL: NSURL) throws { let data = self.dataUsingEncoding(NSUTF8StringEncoding)! try data.appendToURL(fileURL) } } extension NSData { func appendToURL(fileURL: NSURL) throws { if let fileHandle = try? NSFileHandle(forWritingToURL: fileURL) { defer { fileHandle.closeFile() } fileHandle.seekToEndOfFile() fileHandle.writeData(self) } else { try writeToURL(fileURL, options: .DataWritingAtomic) } } } // Test do { let url = NSURL(fileURLWithPath: "test.log") try "Test \(NSDate())".appendLineToURL(url) let result = try String(contentsOfURL: url) } catch { print("Could not write to file") }