从文本文件中读取和写入字符串
Posted
技术标签:
【中文标题】从文本文件中读取和写入字符串【英文标题】:Read and write a String from text file 【发布时间】:2014-07-28 16:02:00 【问题描述】:我需要在文本文件中读取和写入数据,但我无法弄清楚如何。
我在 Swift 的 iBook 中找到了这个示例代码,但我仍然不知道如何写入或读取数据。
import Cocoa
class DataImporter
/*
DataImporter is a class to import data from an external file.
The class is assumed to take a non-trivial amount of time to initialize.
*/
var fileName = "data.txt"
// the DataImporter class would provide data importing functionality here
class DataManager
@lazy var importer = DataImporter()
var data = String[]()
// the DataManager class would provide data management functionality here
let manager = DataManager()
manager.data += "Some data"
manager.data += "Some more data"
// the DataImporter instance for the importer property has not yet been created”
println(manager.importer.fileName)
// the DataImporter instance for the importer property has now been created
// prints "data.txt”
var str = "Hello World in Swift Language."
【问题讨论】:
【参考方案1】:对于读取和写入,您应该使用可写入的位置,例如文档目录。下面的代码展示了如何读取和写入一个简单的字符串。您可以在操场上进行测试。
Swift 3.x - 5.x
let file = "file.txt" //this is the file. we will write to and read from it
let text = "some text" //just a text
if let dir = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first
let fileURL = dir.appendingPathComponent(file)
//writing
do
try text.write(to: fileURL, atomically: false, encoding: .utf8)
catch /* error handling here */
//reading
do
let text2 = try String(contentsOf: fileURL, encoding: .utf8)
catch /* error handling here */
斯威夫特 2.2
let file = "file.txt" //this is the file. we will write to and read from it
let text = "some text" //just a text
if let dir = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.AllDomainsMask, true).first
let path = NSURL(fileURLWithPath: dir).URLByAppendingPathComponent(file)
//writing
do
try text.writeToURL(path, atomically: false, encoding: NSUTF8StringEncoding)
catch /* error handling here */
//reading
do
let text2 = try NSString(contentsOfURL: path, encoding: NSUTF8StringEncoding)
catch /* error handling here */
Swift 1.x
let file = "file.txt"
if let dirs : [String] = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.AllDomainsMask, true) as? [String]
let dir = dirs[0] //documents directory
let path = dir.stringByAppendingPathComponent(file);
let text = "some text"
//writing
text.writeToFile(path, atomically: false, encoding: NSUTF8StringEncoding, error: nil);
//reading
let text2 = String(contentsOfFile: path, encoding: NSUTF8StringEncoding, error: nil)
【讨论】:
let text2 = String.stringWithContentsOfFile(path) // XCode 6.0 使用此解决方案有效,但如果我打开文件,其中没有文本。我错过了什么吗? @Adam 这个文件是什么在 let path = dir.stringByAppendingPathComponent(file);? 这应该被删除,代码不适用于新版本的 Swift。 @billy_b29 此行之后的代码://reading
正是这样做的。【参考方案2】:
假设您已将文本文件 data.txt
移动到 Xcode 项目中(使用拖放操作并选中“如有必要复制文件”),您可以像在 Objective-C 中一样执行以下操作:
let bundle = NSBundle.mainBundle()
let path = bundle.pathForResource("data", ofType: "txt")
let content = NSString.stringWithContentsOfFile(path) as String
println(content) // prints the content of data.txt
更新: 要从 Bundle (ios) 读取文件,您可以使用:
let path = NSBundle.mainBundle().pathForResource("FileName", ofType: "txt")
var text = String(contentsOfFile: path!, encoding: NSUTF8StringEncoding, error: nil)!
println(text)
Swift 3 更新:
let path = Bundle.main.path(forResource: "data", ofType: "txt") // file path for file "data.txt"
var text = String(contentsOfFile: path!, encoding: NSUTF8StringEncoding, error: nil)!
对于 Swift 5
let path = Bundle.main.path(forResource: "ListAlertJson", ofType: "txt") // file path for file "data.txt"
let string = try String(contentsOfFile: path!, encoding: String.Encoding.utf8)
【讨论】:
对于 iOS 项目,“stringWithContentsOfFile”不可用(iOS 7 已弃用) 与 iOS 项目无关,它已被弃用,不再适用于 Xcode 6.1(包括 Mac OS X) 你可以使用 String(contentsOfFile: ...) 类似的解决方案使用捆绑 iOS 10 Swift 3 here【参考方案3】:Xcode 8.x • Swift 3.x 或更高版本
do
// get the documents folder url
if let documentDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first
// create the destination url for the text file to be saved
let fileURL = documentDirectory.appendingPathComponent("file.txt")
// define the string/text to be saved
let text = "Hello World !!!"
// writing to disk
// Note: if you set atomically to true it will overwrite the file if it exists without a warning
try text.write(to: fileURL, atomically: false, encoding: .utf8)
print("saving was successful")
// any posterior code goes here
// reading from disk
let savedText = try String(contentsOf: fileURL)
print("savedText:", savedText) // "Hello World !!!\n"
catch
print("error:", error)
【讨论】:
“没有这样的文件”最常见的错误是什么。因为我将我的 .txt 文件添加到项目导航器,然后我尝试打开它们,所以我收到了这条消息。 (在桌面上创建它们并将它们拖到项目导航器)【参考方案4】:新的更简单的推荐方法: Apple 建议使用 URL 进行文件处理,而这里的其他解决方案似乎已被弃用(请参阅下面的 cmets)。 以下是使用 URL 读写的新的简单方法(不要忘记处理可能的 URL 错误):
Swift 5+、4 和 3.1
import Foundation // Needed for those pasting into Playground
let fileName = "Test"
let dir = try? FileManager.default.url(for: .documentDirectory,
in: .userDomainMask, appropriateFor: nil, create: true)
// If the directory was found, we write a file to it and read it back
if let fileURL = dir?.appendingPathComponent(fileName).appendingPathExtension("txt")
// Write to the file named Test
let outString = "Write this text to the file"
do
try outString.write(to: fileURL, atomically: true, encoding: .utf8)
catch
print("Failed writing to URL: \(fileURL), Error: " + error.localizedDescription)
// Then reading it back from the file
var inString = ""
do
inString = try String(contentsOf: fileURL)
catch
print("Failed reading from URL: \(fileURL), Error: " + error.localizedDescription)
print("Read from the file: \(inString)")
【讨论】:
你能提供一个苹果推荐这种方式的参考吗?或者您能否详细说明为什么这是推荐的方式? @Andrej "URL 对象是引用本地文件的首选方式。大多数从文件读取数据或向文件写入数据的对象都有接受 NSURL 对象而不是路径名作为文件引用的方法。” developer.apple.com/library/ios/documentation/Cocoa/Reference/… 您不必将错误转换为 NSError,甚至不必使用“catch let error”。您只需执行 catch 即可免费获得错误变量。 @cuomo456 你的权利我删除它,它是以前 Swift 测试版的遗留物。 @Alshcompiler create: true 通知 FileManager 如果目录不存在则创建目录,而不是失败【参考方案5】:Xcode 8、Swift 3 从 app bundle 中读取文件的方式:
if let path = Bundle.main.path(forResource: filename, ofType: nil)
do
let text = try String(contentsOfFile: path, encoding: String.Encoding.utf8)
print(text)
catch
printError("Failed to read text from \(filename)")
else
printError("Failed to load file from app bundle \(filename)")
这是一个方便的复制和粘贴扩展
public extension String
func contentsOrBlank()->String
if let path = Bundle.main.path(forResource:self , ofType: nil)
do
let text = try String(contentsOfFile:path, encoding: String.Encoding.utf8)
return text
catch print("Failed to read text from bundle file \(self)")
else print("Failed to load file from bundle \(self)")
return ""
例如
let t = "yourFile.txt".contentsOrBlank()
你几乎总是想要一个行数组:
let r:[String] = "yourFile.txt"
.contentsOrBlank()
.characters
.split(separator: "\n", omittingEmptySubsequences:ignore)
.map(String.init)
【讨论】:
我粘贴了一个方便的扩展@crashalot - 随意删除,干杯 @Alshcompiler 不!您不能将文件写入包中。 我说的是从文件中读取,如果文件在项目文件中,这是唯一对我有用的答案【参考方案6】:我只想向您展示第一部分,即阅读。以下是您可以轻松阅读的方式:
斯威夫特 3:
let s = try String(contentsOfFile: Bundle.main.path(forResource: "myFile", ofType: "txt")!)
斯威夫特 2:
let s = try! String(contentsOfFile: NSBundle.mainBundle().pathForResource("myFile", ofType: "txt")!)
【讨论】:
【参考方案7】:在 Swift > 4.0 中读取文件的最简单方法
let path = Bundle.main.path(forResource: "data", ofType: "txt") // file path for file "data.txt"
do
var text = try String(contentsOfFile: path!)
catch(_)print("error")
【讨论】:
【参考方案8】:您可能会发现这个工具不仅可以在 Swift 中读取文件,还可以解析您的输入:https://github.com/shoumikhin/StreamScanner
只需像这样指定文件路径和数据分隔符:
import StreamScanner
if let input = NSFileHandle(forReadingAtPath: "/file/path")
let scanner = StreamScanner(source: input, delimiters: NSCharacterSet(charactersInString: ":\n")) //separate data by colons and newlines
while let field: String = scanner.read()
//use field
希望,这会有所帮助。
【讨论】:
【参考方案9】:上面亚当当前接受的答案对我来说有一些错误,但这是我如何修改他的答案并使它为我工作的方法。
let file = "file.txt"
let dirs: [String]? = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.AllDomainsMask, true) as? [String]
if (dirs != nil)
let directories:[String] = dirs!
let dirs = directories[0]; //documents directory
let path = dirs.stringByAppendingPathComponent(file);
let text = "some text"
//writing
text.writeToFile(path, atomically: false, encoding: NSUTF8StringEncoding, error: nil);
//reading
var error:NSError?
//reading
let text2 = String(contentsOfFile: path, encoding:NSUTF8StringEncoding, error: &error)
if let theError = error
print("\(theError.localizedDescription)")
【讨论】:
【参考方案10】:为了避免混淆和增加易用性,我创建了两个函数,用于读取和写入文档目录中的文件的字符串。以下是函数:
func writeToDocumentsFile(fileName:String,value:String)
let documentsPath = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] as! NSString
let path = documentsPath.stringByAppendingPathComponent(fileName)
var error:NSError?
value.writeToFile(path, atomically: true, encoding: NSUTF8StringEncoding, error: &error)
func readFromDocumentsFile(fileName:String) -> String
let documentsPath = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] as! NSString
let path = documentsPath.stringByAppendingPathComponent(fileName)
var checkValidation = NSFileManager.defaultManager()
var error:NSError?
var file:String
if checkValidation.fileExistsAtPath(path)
file = NSString(contentsOfFile: path, encoding: NSUTF8StringEncoding, error: nil) as! String
else
file = "*ERROR* \(fileName) does not exist."
return file
以下是它们的使用示例:
writeToDocumentsFile("MyText.txt","Hello world!")
let value = readFromDocumentsFile("MyText.txt")
println(value) //Would output 'Hello world!'
let otherValue = readFromDocumentsFile("SomeText.txt")
println(otherValue) //Would output '*ERROR* SomeText.txt does not exist.'
希望这会有所帮助!
Xcode 版本:6.3.2
【讨论】:
【参考方案11】:这适用于 Linux 上的 Swift 3.1.1:
import Foundation
let s = try! String(contentsOfFile: "yo", encoding: .utf8)
【讨论】:
【参考方案12】:我不得不像这样重新编码:
let path = NSBundle.mainBundle().pathForResource("Output_5", ofType: "xml")
let text = try? NSString(contentsOfFile: path! as String, encoding: NSUTF8StringEncoding)
print(text)
【讨论】:
【参考方案13】:在函数示例中,(read|write)DocumentsFromFile(...) 具有一些函数包装器似乎很有意义,因为 OSx 和 iOS 中的所有内容似乎都需要实例化三到四个主要类和一组配置的属性、链接、实例化和设置,只是为了在 182 个国家/地区将“Hi”写入文件。
但是,这些示例还不够完整,无法在实际程序中使用。 write 函数不会报告创建或写入文件的任何错误。在读取时,我认为返回文件不存在作为应该包含已读取数据的字符串的错误不是一个好主意。您会想通过某种通知机制(例如异常)知道它失败以及失败的原因。然后,您可以编写一些代码来输出问题所在并允许用户更正它,或者“正确地”在该点中断程序。
您不想只返回一个包含“错误文件不存在”的字符串。然后,您必须每次从调用函数中查找字符串中的错误并在那里处理它。您也可能无法真正判断错误字符串是否实际上是从实际文件中读取的,或者它是否是从您的代码中产生的。
您甚至不能在 swift 2.2 和 Xcode 7.3 中这样调用 read,因为 NSString(contentsOfFile...) 会引发异常。如果您没有任何代码来捕获它并对其执行某些操作,例如将其打印到 stdout,或者更好的是错误弹出窗口或 stderr,则这是一个编译时错误。我听说 Apple 正在远离 try catch 和异常,但这将是一个漫长的过程,没有它就不可能编写代码。我不知道 &error 参数来自哪里,可能是旧版本,但是 NSString.writeTo[File|URL] 目前没有 NSError 参数。它们在 NSString.h 中是这样定义的:
public func writeToURL(url: NSURL, atomically useAuxiliaryFile: Bool, encoding enc: UInt) throws
public func writeToFile(path: String, atomically useAuxiliaryFile: Bool, encoding enc: UInt) throws
public convenience init(contentsOfURL url: NSURL, encoding enc: UInt) throws
public convenience init(contentsOfFile path: String, encoding enc: UInt) throws
此外,不存在的文件只是您的程序在读取文件时可能遇到的许多潜在问题之一,例如权限问题、文件大小或您甚至不想尝试编码的许多其他问题每个人都有一个处理程序。最好假设一切都是正确的,然后捕获并打印或处理异常,如果出现问题,此外,在这一点上,您实际上别无选择。
这是我的重写:
func writeToDocumentsFile(fileName:String,value:String)
let documentsPath = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] as NSString!
let path = documentsPath.stringByAppendingPathComponent(fileName)
do
try value.writeToFile(path, atomically: true, encoding: NSUTF8StringEncoding)
catch let error as NSError
print("ERROR : writing to file \(path) : \(error.localizedDescription)")
func readFromDocumentsFile(fileName:String) -> String
let documentsPath = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] as NSString
let path = documentsPath.stringByAppendingPathComponent(fileName)
var readText : String = ""
do
try readText = NSString(contentsOfFile: path, encoding: NSUTF8StringEncoding) as String
catch let error as NSError
print("ERROR : reading from file \(fileName) : \(error.localizedDescription)")
return readText
【讨论】:
在您的许多回复中,我认为您没有理解我的观点。 (或者你可能不在乎,没关系)。但是,需要明确的是,在查找不存在的文件(或存在其他问题,例如权限)时,抛出异常并以某种方式处理它比返回诸如“错误:文件 [文件名]”之类的字符串要好得多不存在”作为您应该从文件中实际读取的字符串。然后就打印那个。如果有任何内容,您应该打印异常详细信息,而不是现在有错误的无法读取的字符串。程序可能不应该继续。【参考方案14】:因为我的 txt 文件是这样工作的:
let myFileURL = NSBundle.mainBundle().URLForResource("listacomuni", withExtension: "txt")!
let myText = try! String(contentsOfURL: myFileURL, encoding: NSISOLatin1StringEncoding)
print(String(myText))
【讨论】:
【参考方案15】:最新的 swift3 代码 您可以从文本文件中读取数据,只需使用以下代码 这是我的文本文件
"NumberOfSlices": "8",
"NrScenes": "5",
"Scenes": [
"dataType": "label1",
"image":"http://is3.mzstatic.com/image/thumb/Purple19/v4/6e/81/31/6e8131cf-2092-3cd3-534c-28e129897ca9/mzl.syvaewyp.png/53x53bb-85.png",
"value": "Hello",
"color": "(UIColor.red)"
,
"dataType": "label2",
"image":"http://is1.mzstatic.com/image/thumb/Purple71/v4/6c/4c/c1/6c4cc1bc-8f94-7b13-f3aa-84c41443caf3/mzl.hcqvmrix.png/53x53bb-85.png",
"value": "Hi There",
"color": "(UIColor.blue)"
,
"dataType": "label3",
"image":"http://is1.mzstatic.com/image/thumb/Purple71/v4/6c/4c/c1/6c4cc1bc-8f94-7b13-f3aa-84c41443caf3/mzl.hcqvmrix.png/53x53bb-85.png",
"value": "hi how r u ",
"color": "(UIColor.green)"
,
"dataType": "label4",
"image":"http://is1.mzstatic.com/image/thumb/Purple71/v4/6c/4c/c1/6c4cc1bc-8f94-7b13-f3aa-84c41443caf3/mzl.hcqvmrix.png/53x53bb-85.png",
"value": "what are u doing ",
"color": "(UIColor.purple)"
,
"dataType": "label5",
"image":"http://is1.mzstatic.com/image/thumb/Purple71/v4/6c/4c/c1/6c4cc1bc-8f94-7b13-f3aa-84c41443caf3/mzl.hcqvmrix.png/53x53bb-85.png",
"value": "how many times ",
"color": "(UIColor.white)"
,
"dataType": "label6",
"image":"http://is1.mzstatic.com/image/thumb/Purple71/v4/5a/f3/06/5af306b0-7cac-1808-f440-bab7a0d18ec0/mzl.towjvmpm.png/53x53bb-85.png",
"value": "hi how r u ",
"color": "(UIColor.blue)"
,
"dataType": "label7",
"image":"http://is5.mzstatic.com/image/thumb/Purple71/v4/a8/dc/eb/a8dceb29-6daf-ca0f-d037-df9f34cdc476/mzl.ukhhsxik.png/53x53bb-85.png",
"value": "hi how r u ",
"color": "(UIColor.gry)"
,
"dataType": "label8",
"image":"http://is2.mzstatic.com/image/thumb/Purple71/v4/15/23/e0/1523e03c-fff2-291e-80a7-73f35d45c7e5/mzl.zejcvahm.png/53x53bb-85.png",
"value": "hi how r u ",
"color": "(UIColor.brown)"
]
您可以使用此代码从 swift3 中的文本 json 文件中获取数据
let filePath = Bundle.main.path(forResource: "nameoftheyourjsonTextfile", ofType: "json")
let contentData = FileManager.default.contents(atPath: filePath!)
let content = NSString(data: contentData!, encoding: String.Encoding.utf8.rawValue) as? String
print(content)
let json = try! JSONSerialization.jsonObject(with: contentData!) as! NSDictionary
print(json)
let app = json.object(forKey: "Scenes") as! NSArray!
let _ : NSDictionary
for dict in app!
let colorNam = (dict as AnyObject).object(forKey: "color") as! String
print("colors are \(colorNam)")
// let colour = UIColor(hexString: colorNam)
// colorsArray.append(colour.cgColor)
// colorsArray.append(colorNam as! UIColor)
let value = (dict as AnyObject).object(forKey: "value") as! String
print("the values are \(value)")
valuesArray.append(value)
let images = (dict as AnyObject).object(forKey: "image") as! String
let url = URL(string: images as String)
let data = try? Data(contentsOf: url!)
print(data)
let image1 = UIImage(data: data!)! as UIImage
imagesArray.append(image1)
print(image1)
【讨论】:
【参考方案16】:推荐异步读写文件!在纯 Swift 中很容易做到, 这是协议:
protocol FileRepository
func read(from path: String) throws -> String
func readAsync(from path: String, completion: @escaping (Result<String, Error>) -> Void)
func write(_ string: String, to path: String) throws
func writeAsync(_ string: String, to path: String, completion: @escaping (Result<Void, Error>) -> Void)
如您所见,它允许您同步或异步读取和写入文件。
这是我在 Swift 5 中的实现:
class DefaultFileRepository
// MARK: Properties
let queue: DispatchQueue = .global()
let fileManager: FileManager = .default
lazy var baseURL: URL =
try! fileManager
.url(for: .libraryDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
.appendingPathComponent("MyFiles")
()
// MARK: Private functions
private func doRead(from path: String) throws -> String
let url = baseURL.appendingPathComponent(path)
var isDir: ObjCBool = false
guard fileManager.fileExists(atPath: url.path, isDirectory: &isDir) && !isDir.boolValue else
throw ReadWriteError.doesNotExist
let string: String
do
string = try String(contentsOf: url)
catch
throw ReadWriteError.readFailed(error)
return string
private func doWrite(_ string: String, to path: String) throws
let url = baseURL.appendingPathComponent(path)
let folderURL = url.deletingLastPathComponent()
var isFolderDir: ObjCBool = false
if fileManager.fileExists(atPath: folderURL.path, isDirectory: &isFolderDir)
if !isFolderDir.boolValue
throw ReadWriteError.canNotCreateFolder
else
do
try fileManager.createDirectory(at: folderURL, withIntermediateDirectories: true)
catch
throw ReadWriteError.canNotCreateFolder
var isDir: ObjCBool = false
guard !fileManager.fileExists(atPath: url.path, isDirectory: &isDir) || !isDir.boolValue else
throw ReadWriteError.canNotCreateFile
guard let data = string.data(using: .utf8) else
throw ReadWriteError.encodingFailed
do
try data.write(to: url)
catch
throw ReadWriteError.writeFailed(error)
extension DefaultFileRepository: FileRepository
func read(from path: String) throws -> String
try queue.sync try self.doRead(from: path)
func readAsync(from path: String, completion: @escaping (Result<String, Error>) -> Void)
queue.async
do
let result = try self.doRead(from: path)
completion(.success(result))
catch
completion(.failure(error))
func write(_ string: String, to path: String) throws
try queue.sync try self.doWrite(string, to: path)
func writeAsync(_ string: String, to path: String, completion: @escaping (Result<Void, Error>) -> Void)
queue.async
do
try self.doWrite(string, to: path)
completion(.success(Void()))
catch
completion(.failure(error))
enum ReadWriteError: LocalizedError
// MARK: Cases
case doesNotExist
case readFailed(Error)
case canNotCreateFolder
case canNotCreateFile
case encodingFailed
case writeFailed(Error)
【讨论】:
这可以用来从 AppBundle 读取文件吗?例如位于appBundle/MyTextFiles/changes.txt
的文件?【参考方案17】:
在 ViewDidLoad 中写入
var error: NSError?
var paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, NSSearchPathDomainMask.UserDomainMask, true)
var documentsDirectory = paths.first as String
var dataPath = documentsDirectory.stringByAppendingPathComponent("MyFolder")
if !NSFileManager.defaultManager().fileExistsAtPath(dataPath)
NSFileManager.defaultManager().createDirectoryAtPath(dataPath, withIntermediateDirectories: false, attributes: nil, error: &error)
else
println("not creted or exist")
func listDocumentDirectoryfiles() -> [String]
if let documentDirectory = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true).first as? String
let myFilePath = documentDirectory.stringByAppendingPathComponent("MyFolder")
return NSFileManager.defaultManager().contentsOfDirectoryAtPath(myFilePath, error: nil) as [String]
return []
【讨论】:
【参考方案18】: func writeToDocumentsFile(fileName:String,value:String)
let documentsPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] as NSString
let path = documentsPath.appendingPathComponent(fileName)
do
try value.write(toFile: path, atomically: true, encoding: String.Encoding.utf8)
catch
func readFromDocumentsFile(fileName:String) -> String
let documentsPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] as NSString
let path = documentsPath.appendingPathComponent(fileName)
let checkValidation = FileManager.default
var file:String
if checkValidation.fileExists(atPath: path)
do
try file = NSString(contentsOfFile: path, encoding: String.Encoding.utf8.rawValue) as String
catch
file = ""
else
file = ""
return file
【讨论】:
【参考方案19】:早期的解决方案回答了问题,但在我的情况下,在写入时删除文件的旧内容是一个问题。
所以,我创建了一段代码,用于写入文档目录中的文件,而不删除以前的内容。您可能需要更好的错误处理,但我相信这是一个很好的起点。斯威夫特 4。 用法:
let filename = "test.txt"
createOrOverwriteEmptyFileInDocuments(filename: filename)
if let handle = getHandleForFileInDocuments(filename: filename)
writeString(string: "aaa", fileHandle: handle)
writeString(string: "bbb", fileHandle: handle)
writeString(string: "\n", fileHandle: handle)
writeString(string: "ccc", fileHandle: handle)
辅助方法:
func createOrOverwriteEmptyFileInDocuments(filename: String)
guard let dir = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first else
debugPrint("ERROR IN createOrOverwriteEmptyFileInDocuments")
return
let fileURL = dir.appendingPathComponent(filename)
do
try "".write(to: fileURL, atomically: true, encoding: .utf8)
catch
debugPrint("ERROR WRITING STRING: " + error.localizedDescription)
debugPrint("FILE CREATED: " + fileURL.absoluteString)
private func writeString(string: String, fileHandle: FileHandle)
let data = string.data(using: String.Encoding.utf8)
guard let dataU = data else
debugPrint("ERROR WRITING STRING: " + string)
return
fileHandle.seekToEndOfFile()
fileHandle.write(dataU)
private func getHandleForFileInDocuments(filename: String)->FileHandle?
guard let dir = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first else
debugPrint("ERROR OPENING FILE")
return nil
let fileURL = dir.appendingPathComponent(filename)
do
let fileHandle: FileHandle? = try FileHandle(forWritingTo: fileURL)
return fileHandle
catch
debugPrint("ERROR OPENING FILE: " + error.localizedDescription)
return nil
【讨论】:
【参考方案20】:Swift 3.x - 5.x
最好的例子是创建一个本地的Logfile
,扩展名为.txt
可以在"Files App"
中以当前日期和时间作为文件名可见和显示
只需在 info.plist 中添加此代码即可启用这两个功能
UIFileSharingEnabled
LSSupportsOpeningDocumentsInPlace
下面这个函数
var logfileName : String = ""
func getTodayString() -> String
let date = Date()
let calender = Calendar.current
let components = calender.dateComponents([.year,.month,.day,.hour,.minute,.second], from: date)
let year = components.year
let month = components.month
let day = components.day
let hour = components.hour
let minute = components.minute
let second = components.second
let today_string = String(year!) + "-" + String(month!) + "-" + String(day!) + "-" + String(hour!) + "" + String(minute!) + "" + String(second!)+".txt"
return today_string
func LogCreator()
logfileName = getTodayString()
print("LogCreator: Logfile Generated Named: \(logfileName)")
let file = logfileName //this is the file. we will write to and read from it
let text = "some text" //just a text
if let dir = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first
let fileURL = dir.appendingPathComponent(file)
let documentPath = NSSearchPathForDirectoriesInDomains(.documentDirectory,.userDomainMask, true)[0]
print("LogCreator: The Logs are Stored at location \(documentPath)")
//writing
do
try text.write(to: fileURL, atomically: false, encoding: .utf8)
catch /* error handling here */
//reading
do
let text2 = try String(contentsOf: fileURL, encoding: .utf8)
print("LogCreator: The Detail log are :-\(text2)")
catch /* error handling here */
[1]: https://i.stack.imgur.com/4eg12.png
【讨论】:
我试过这个,但一定漏掉了什么。它保存我的文档并将其放入 file:///var/mobile/Containers/Data/Application/E4BF1065-3B48-4E53-AC1D-0DC893CCB498/Documents/ 但我无法在文件中找到它。 我错过了这个键...Xcode 8.3.2 Swift 3.x。使用 NSKeyedArchiver 和 NSKeyedUnarchiver
从文档中读取文件
let documentsDirectoryPathString = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first!
let documentsDirectoryPath = NSURL(string: documentsDirectoryPathString)!
let jsonFilePath = documentsDirectoryPath.appendingPathComponent("Filename.json")
let fileManager = FileManager.default
var isDirectory: ObjCBool = false
if fileManager.fileExists(atPath: (jsonFilePath?.absoluteString)!, isDirectory: &isDirectory)
let finalDataDict = NSKeyedUnarchiver.unarchiveObject(withFile: (jsonFilePath?.absoluteString)!) as! [String: Any]
else
print("File does not exists")
将文件写入文档
NSKeyedArchiver.archiveRootObject(finalDataDict, toFile:(jsonFilePath?.absoluteString)!)
【讨论】:
以上是关于从文本文件中读取和写入字符串的主要内容,如果未能解决你的问题,请参考以下文章