Добавить текст или данные в текстовый файл в Swift

Я уже прочитал Чтение и запись данных из текстового файла

Мне нужно добавить данные (строку) в конец текстового файла.
Один очевидный способ сделать это – прочитать файл с диска и добавить строку до конца и записать ее обратно, но она неэффективна, особенно если вы имеете дело с большими файлами и делаете это часто.

Поэтому возникает вопрос: «Как добавить строку в конец текстового файла, не читая файл и не записывая все это»?

до сих пор я имею:

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, с одной быстрой записью – при тестировании игровой площадки с использованием простой файловой политики, но в моем фактическом приложении мне нужно было создать URL-адрес, используя .documentDirectory (или какой-либо каталог, который вы выбрали для чтения и написание – убедитесь, что это согласовано во всем приложении):

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

    Обновление: я написал сообщение в блоге об этом, которое вы можете найти здесь !

    Сохранение вещей Swifty , вот пример использования протокола FileWriter с реализацией по умолчанию (Swift 4.1 на момент написания этой статьи):

    • Чтобы использовать это, пусть ваш объект (class, структура, перечисление) соответствует этому протоколу и вызовет функцию записи (fyi, it throws!).
    • Записывает каталог документов.
    • Будет добавлен в текстовый файл, если файл существует.
    • Создает новый файл, если текстовый файл не существует.
    • Примечание: это только текст. Вы можете сделать что-то похожее на запись / добавление Data .

       import Foundation enum FileWriteError: Error { case directoryDoesntExist case convertToDataIssue } protocol FileWriter { var fileName: String { get } func write(_ text: String) throws } extension FileWriter { var fileName: String { return "File.txt" } func write(_ text: String) throws { guard let dir = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first else { throw FileWriteError.directoryDoesntExist } let encoding = String.Encoding.utf8 guard let data = text.data(using: encoding) else { throw FileWriteError.convertToDataIssue } let fileUrl = dir.appendingPathComponent(fileName) if let fileHandle = FileHandle(forWritingAtPath: fileUrl.path) { fileHandle.seekToEndOfFile() fileHandle.write(data) } else { try text.write(to: fileUrl, atomically: false, encoding: encoding) } } } 

    Чтобы остаться в духе PointZero Two. Здесь обновлен его код для Swift 4.1

     extension String { func appendLine(to url: URL) throws { try self.appending("\n").append(to: url) } func append(to url: URL) throws { let data = self.data(using: String.Encoding.utf8) try data?.append(to: url) } } extension Data { func append(to url: URL) throws { if let fileHandle = try? FileHandle(forWritingTo: url) { defer { fileHandle.closeFile() } fileHandle.seekToEndOfFile() fileHandle.write(self) } else { try write(to: url) } } } 
    Давайте будем гением компьютера.