/ / Pripojte text alebo dáta k textovému súboru v aplikácii Swift - rýchle, pripojte, textové súbory

Pripojiť text alebo údaje k textovému súboru v aplikácii Swift - rýchle, pripojiť, textové súbory

Už mám prečítané Čítanie a zápis údajov z textového súboru

Potrebujem pripojiť údaje (reťazec) na koniec môjho textového súboru.
Jedným zo zrejmých spôsobov, ako to urobiť, je prečítať súbor zdisk a pripojte reťazec na jeho koniec a odpíšte ho späť, ale nie je to efektívne, najmä ak pracujete s veľkými súbormi a často robíte.

Otázka teda znie: „Ako pripojiť reťazec na koniec textového súboru bez toho, aby ste si ho prečítali a celý napísali späť“?

zatiaľ som:

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

odpovede:

27 pre odpoveď č. 1

Mali by ste použiť NSFileHandle hľadať na konci spisu

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

25 pre odpoveď č. 2

Toto je aktualizácia odpovede aplikácie PointZeroTwo v systéme WindowsSwift 3.0, s jednou rýchlou poznámkou - pri testovaní ihriska pomocou jednoduchej cesty k súboru funguje, ale v mojej skutočnej aplikácii som potreboval vytvoriť adresu URL pomocou konzistentné v celej vašej aplikácii):

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

Vďaka PointZeroTwo.


14 pre odpoveď č. 3

Toto je verzia pre Swift 2, ktorá používa metódy rozšírenia na reťazcoch String a 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")
}

1 pre odpoveď č. 4

Aktualizácia: Napísal som k tomu blogový príspevok, ktorý nájdete tu!

Udržiavanie vecí Šikovný, tu je príklad použitia a FileWriter protokol s predvolenou implementáciou (v čase písania tohto dokumentu Swift 4.1):

  • Ak to chcete použiť, nechajte svoju entitu (triedu, štruktúru, výčet) vyhovovať tomuto protokolu a zavolajte funkciu zápisu (fyi, to hodí!).
  • Zápis do adresára dokumentov.
  • Pripojí sa k textovému súboru, ak súbor existuje.
  • Vytvorí nový súbor, ak textový súbor neexistuje.
  • Poznámka: toto je iba pre text. Mohli by ste urobiť niečo podobné ako napísať / pridať 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 pre odpoveď č. 5

Aby sme zostali v duchu PointZero Two. Tu aktualizácia jeho kódu pre 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)
}
}
}