Skip to content

Instantly share code, notes, and snippets.

@akingdom
Last active September 28, 2023 19:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save akingdom/436301490426b21f7591adbf31ce67bd to your computer and use it in GitHub Desktop.
Save akingdom/436301490426b21f7591adbf31ce67bd to your computer and use it in GitHub Desktop.
Read a single line string from a file
// Swift
//
// Intent: Read a single line string from a file, with some memory efficiency.
// This could be improved by use of an (unsafe) memory buffer
//
// By Andrew Kingdom
// MIT license
//
class ReadLineTool {
static func readLine(from fileHandle: FileHandle) throws -> String? {
let bufferSize = 4096
let newline = Data.Element(0x0A)
// Gets the position of the file pointer within the file.
let offset: UInt64 = try fileHandle.offset()
// Create a Data object from the file handle.
var data = Data()
// Read data from the file handle until we encounter a newline character.
while let chunk = try fileHandle.read(upToCount: bufferSize) {
data.append(chunk)
if let newlineIndex = data.firstIndex(of: newline) {
// We found a newline character. Return the line up to the newline character.
guard let line = String(data: data[0..<newlineIndex], encoding: .utf8) else {
// The data is not encoded in UTF-8.
return nil
}
let lineSize = line.lengthOfBytes(using: .utf8)
// Reset the file position index to one character after the found newline.
try fileHandle.seek(toOffset: offset + UInt64(lineSize + 1))
return line
}
}
// If we reach the end of the file without finding a newline character, return the remaining data as the line.
if data.count > 0 {
guard let line = String(data: data, encoding: .utf8) else {
// The data is not encoded in UTF-8.
return nil
}
return line
}
// If we reach this point, there is no more data to read from the file.
return nil
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment