DispatchQueue.global(qos: .background).async {
guard let path = Bundle.main.path(forResource: "graphics", ofType: "txt") else {
print("Dang! File wasn't found!")
return
}
let cal = Calendar.current
let d1 = Date()
guard let streamReader = StreamReader(path: path) else {
print("Dang! StreamReader couldn't be created!")
return
}
var counter = 0
while !streamReader.atEof {
guard let nextLine = streamReader.nextLine() else {
print("Oops! Reached the end before printing!")
break
}
let json = JSON(parseJSON: nextLine)
counter += 1
print("\(counter): \(nextLine)")
}
let d2 = Date()
let components = cal.dateComponents([.minute], from: d2, to: d1)
print("Diff: \(components.minute!)")
}
}
Класс Stream Reader
import Foundation
class StreamReader {
let encoding : String.Encoding
let chunkSize : Int
var fileHandle : FileHandle!
let delimData : Data
var buffer : Data
var atEof : Bool
init?(path: String, delimiter: String = "\n", encoding: String.Encoding = .utf8,
chunkSize: Int = 4096) {
guard let fileHandle = FileHandle(forReadingAtPath: path),
let delimData = delimiter.data(using: encoding) else {
return nil
}
self.encoding = encoding
self.chunkSize = chunkSize
self.fileHandle = fileHandle
self.delimData = delimData
self.buffer = Data(capacity: chunkSize)
self.atEof = false
}
deinit {
self.close()
}
/// Return next line, or nil on EOF.
func nextLine() -> String? {
precondition(fileHandle != nil, "Attempt to read from closed file")
// Read data chunks from file until a line delimiter is found:
while !atEof {
if let range = buffer.range(of: delimData) {
// Convert complete line (excluding the delimiter) to a string:
let line = String(data: buffer.subdata(in: 0..<range.lowerBound), encoding: encoding)
// Remove line (and the delimiter) from the buffer:
buffer.removeSubrange(0..<range.upperBound)
return line
}
let tmpData = fileHandle.readData(ofLength: chunkSize)
if tmpData.count > 0 {
buffer.append(tmpData)
} else {
// EOF or read error.
atEof = true
if buffer.count > 0 {
// Buffer contains last line in file (not terminated by delimiter).
let line = String(data: buffer as Data, encoding: encoding)
buffer.count = 0
return line
}
}
}
return nil
}
/// Start reading from the beginning of file.
func rewind() -> Void {
fileHandle.seek(toFileOffset: 0)
buffer.count = 0
atEof = false
}
/// Close the underlying file. No reading must be done after calling this method.
func close() -> Void {
fileHandle?.closeFile()
fileHandle = nil
}
}
extension StreamReader : Sequence {
func makeIterator() -> AnyIterator<String> {
return AnyIterator {
return self.nextLine()
}
}
}
Класс StreamReader читает текстовый файл построчно, поэтому нет необходимости читать весь файл сразу.первый блок читает содержимое файла.Попробуйте приведенный выше код.это должно решить вашу проблему.обратите внимание, что я использовал фоновый поток, тогда как область не работает в фоновом потоке (AFAIK).дайте мне знать, если это поможет.