Swift:流式传输/写出CSV文件

时间:2017-03-03 12:12:59

标签: swift csv

我正在使用手机记录一些传感器数据并通过SQLite通过SharkORM(DBAccess)将其存储在设备上。

我现在想把这些数据写到CSV文件中,但是现在我有160万条记录。

目前,我正在循环遍历1000条记录,将它们添加到字符串中,最后将它们写出来。但是,必须有更好的方法来做到这一点吗?

func writeRawFile()
    {
        let fileName = "raw"
        let DocumentDirURL = try! FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true)

        let fileURL = DocumentDirURL.appendingPathComponent(fileName).appendingPathExtension("csv")

        var data = "time,lat,lon,speed,x_acc,y_acc,z_acc,gyro_x,gyro_y,gyro_z,compass,orientation\r\n"

        let count = RawReading.query().count()
        var counter = 0;
        let df = DateFormatter()
        df.dateFormat = "y-MM-dd H:m:ss.SSSS"

        for i in stride(from:0, to: count, by: 1000)
        {
            autoreleasepool {

                for result in RawReading.query().offset(Int32(i)).limit(1000).fetch()
                {
                    if let raw : RawReading = result as? RawReading
                    {
                        if (Double(raw.speed!) > 3.0) //1 Meter per Second = 2.236936 Miles per Hour
                        {
                            //print(df.string(from: raw.date!))

                            data += "\(df.string(from: raw.date!)),\(raw.lat!),\(raw.lon!),\(raw.speed!),\(raw.x!),\(raw.y!),\(raw.z!),\(raw.xx!),\(raw.yy!),\(raw.zz!),\(raw.compass!),\(raw.orientation!)" + "\r\n"

                            counter += 1
                        }

                    }
                }

                print ("Written \(i) of \(count)")

            }
        }

        print("Count \(count) \(counter)")

        //write the file, return true if it works, false otherwise.
        do{
            try data.write(to: fileURL, atomically: true, encoding: String.Encoding.utf8 )
        } catch{
            print("error")
        }
    }

1 个答案:

答案 0 :(得分:5)

打开FileHandle进行写入,然后分别构建和编写每一行,这样就不必保留整个文件内容 在记忆中:

do {
    let file = try FileHandle(forWritingTo: fileURL)
    defer { file.closeFile() }

    for <... your loop ...> {
        let line = ... // build one CSV line
        file.write(line.data(using: .utf8)!)
    }

} catch let error {
    // ...
}

您也可以先写入临时文件,然后将其重命名为 实际文件,以避免文件损坏,如果有的话 出了问题。