Запись нескольких строк текста в документ txt swift [duplicate]

Что сработало для меня, было удалить ~/.purple/prefs.xml. Потерял множество предпочтений (группы и прочее), но, по крайней мере, окно вернулось.

23
задан 23 May 2017 в 14:47

5 ответов

Вот обновление для ответа 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.

25
ответ дан 15 August 2018 в 17:02

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

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

Чтобы использовать это, ваша сущность (класс, структура, перечисление) должна соответствовать этому протоколу и вызвать функцию записи (fyi, it throws!). Записывает каталог документов. Будет добавлен в текстовый файл, если файл существует. Создает новый файл, если текстовый файл не существует. Примечание: это только текст. Вы можете сделать что-то подобное записи / append 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)
        }
    }
}
1
ответ дан 15 August 2018 в 17:02

Чтобы остаться в духе 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)
        }
    }
}
1
ответ дан 15 August 2018 в 17:02

Вы должны использовать 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)")
    }
}
27
ответ дан 15 August 2018 в 17:02
  • 1
    Можете ли вы предоставить быструю версию этого кода? – Vaibhav Jhaveri 19 January 2017 в 08:35
  • 2
    Вы были бы поражены тем, насколько легко преобразовать это в быстрое 3, если вы просто нажмете на эти маленькие красные круги с белыми точками в Xcode. – Chris 18 March 2017 в 07:02

Вот версия для 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")
}
14
ответ дан 15 August 2018 в 17:02
  • 1
    нет необходимости импортировать UIKit, нет? – Hugues BR 28 June 2016 в 12:13

Другие вопросы по тегам:

Похожие вопросы: