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ď č. 1Mali 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)
}
}
}