Created
June 30, 2020 10:52
-
-
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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