写入文件的有效方法,swift

时间:2016-08-01 11:41:27

标签: ios swift

我使用蓝牙从传感器获取数据,我想将我得到的数据串附加到文件末尾。

当我尝试常规方法时

if let dir = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.AllDomainsMask, true).first {
        let path = NSURL(fileURLWithPath: dir).URLByAppendingPathComponent(self.file)

        do {
            try text.writeToURL(path, atomically: false, encoding: NSUTF8StringEncoding)
        }
        catch {/* error handling here */}

我的应用程序开始变慢,直到标签不再更新为止。

尝试使用dispatch_async在后​​台线程中执行,但仍然会减慢我的应用。

我应该使用什么方法?我读过关于流的信息,但未能找到一些我可以依赖的快速解决方案

3 个答案:

答案 0 :(得分:3)

可能您的蓝牙读取数据的速度比执行文件操作的速度快。您可以通过将文本附加到文件而不是读取每个写入操作的所有内容来优化它。您还可以在写入之间重用文件处理程序并保持文件打开。

此示例摘自this answer

struct MyStreamer: OutputStreamType {
    lazy var fileHandle: NSFileHandle? = {
        let fileHandle = NSFileHandle(forWritingAtPath: self.logPath)
        return fileHandle
    }()

    lazy var logPath: String = {
        let path : NSString = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.AllDomainsMask, true).first!
        let filePath = (path as NSString).stringByAppendingPathComponent("log.txt")

        if !NSFileManager.defaultManager().fileExistsAtPath(filePath) {
            NSFileManager.defaultManager().createFileAtPath(filePath, contents: nil, attributes: nil)
        }
        print(filePath)
        return filePath

    }()

    mutating func write(string: String) {
        print(fileHandle)
        fileHandle?.seekToEndOfFile()
        fileHandle?.writeData(string.dataUsingEncoding(NSUTF8StringEncoding)!)
    }
}

然后,您可以创建单个流转化器并在不同的写入中重复使用它:

var myStream = MyStreamer()
myStream.write("First of all")
myStream.write("Then after")
myStream.write("And, finally")

在这种情况下,您有MyStreamer也是OutputStreamType的奖励,因此您可以像这样使用它:

var myStream = MyStreamer()
print("First of all", toStream: &myStream )
print("Then after", toStream: &myStream)
print("And, finally", toStream: &myStream)

最后,我建议您将'log.txt'字符串移动到实例变量并将其作为构造函数参数传递:

var myStream = MyStreamer("log.txt")

有关the Apple Docs中文件处理程序的详细信息。

答案 1 :(得分:1)

更新@ redent84,以在 Swift 5

中工作

代码:

struct MyStreamer{
    lazy var fileHandle = FileHandle(forWritingAtPath: logPath)


    lazy var logPath: String = {
        let path = NSSearchPathForDirectoriesInDomains(.documentDirectory, .allDomainsMask, true)[0]
        let filePath = path + "/log.txt"
        if FileManager.default.fileExists(atPath: filePath) == false{
            FileManager.default.createFile(atPath: filePath, contents: nil, attributes: nil)
        }
        print(filePath)
        return filePath

    }()

    mutating func write(_ string: String) {
        print(fileHandle?.description ?? "呵呵")
        fileHandle?.seekToEndOfFile()
        if let data = string.data(using: String.Encoding.utf8){
            fileHandle?.write(data)
        }
    }
}

用法:

var myStream = MyStreamer()
myStream.write("First of all")
myStream.write("Then after")
myStream.write("And, finally")

答案 2 :(得分:0)

尝试写这样的文件..

var paths: [AnyObject] = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)
let filePath = paths[0].stringByAppendingString("/filename.mov")

do 
   {
     try NSFileManager.defaultManager().removeItemAtURL(outputURL)
   }
catch  
  {

            error as NSError
   }

do {
    try text.writeToURL(path, atomically: false, encoding: NSUTF8StringEncoding)
    }

我的意思是说最后你必须先删除..如果有任何疑问你可以问我