Skip to content

Instantly share code, notes, and snippets.

@lalkrishna
Created June 30, 2020 10:52
Show Gist options
  • Save lalkrishna/c5e2023261fc5f247666068ec9730de6 to your computer and use it in GitHub Desktop.
Save lalkrishna/c5e2023261fc5f247666068ec9730de6 to your computer and use it in GitHub Desktop.
If you need to read a very large file you’ll want to stream it so you’re not loading the entire thing into memory at once. Here’s a snippet for doing that.
class UseItHere {
func readFile() {
let fileReader = StreamingFileReader(path: logFile)
while let line = fileReader.readLine() {
// Do something with the line
}
}
}
class StreamingFileReader {
var fileHandle: FileHandle?
var buffer: Data
let bufferSize: Int = 1024
// Using new line as the delimiter
let delimiter = "\n".data(using: .utf8)!
init(path: String) {
fileHandle = FileHandle(forReadingAtPath: path)
buffer = Data(capacity: bufferSize)
}
func readLine() -> String? {
var rangeOfDelimiter = buffer.range(of: delimiter)
while rangeOfDelimiter == nil {
guard let chunk = fileHandle?.readData(ofLength: bufferSize) else { return nil }
if chunk.count == 0 {
if buffer.count > 0 {
defer { buffer.count = 0 }
return String(data: buffer, encoding: .utf8)
}
return nil
} else {
buffer.append(chunk)
rangeOfDelimiter = buffer.range(of: delimiter)
}
}
let rangeOfLine = 0 ..< rangeOfDelimiter!.upperBound
let line = String(data: buffer.subdata(in: rangeOfLine), encoding: .utf8)
buffer.removeSubrange(rangeOfLine)
return line?.trimmingCharacters(in: .whitespacesAndNewlines)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment