Я вижу, что многие из этих ответов полагаются на чтение всего текстового файла в память вместо того, чтобы брать его по частям. Вот мое решение в красивом современном Swift, использующее FileHandle для снижения воздействия на память:
enum MyError {
case invalidTextFormat
}
extension FileHandle {
func readLine(maxLength: Int) throws -> String {
let offset = offsetInFile
let data = readData(ofLength: maxLength)
guard let string = String(data: data, encoding: .utf8) else {
throw MyError.invalidTextFormat
}
let substring: String
if let subindex = string.firstIndex(of: "\n") {
substring = String(string[string.startIndex ... subindex])
} else {
substring = string
}
guard let dataCount = substring.data(using: .utf8, allowLossyConversion: false)?.count else {
throw MyError.invalidTextFormat
}
try seek(toOffset: offset + UInt64(dataCount))
return substring
}
}
Обратите внимание, что это сохраняет возврат каретки в конце строки, поэтому в зависимости от ваших потребностей вы можете изменить код, чтобы удалить его.
Использование: просто откройте дескриптор целевого текстового файла и вызовите readLine
подходящую максимальную длину - 1024 является стандартным для обычного текста, но я оставил его открытым на случай, если вы знаете, что он будет короче. Обратите внимание, что команда не переполняет конец файла, поэтому вам, возможно, придется вручную проверить, что вы не достигли его, если вы собираетесь анализировать все это. Вот пример кода, который показывает, как открыть файл myFileURL
и прочитать его построчно до конца.
do {
let handle = try FileHandle(forReadingFrom: myFileURL)
try handle.seekToEndOfFile()
let eof = handle.offsetInFile
try handle.seek(toFileOffset: 0)
while handle.offsetInFile < eof {
let line = try handle.readLine(maxLength: 1024)
}
try handle.close()
catch let error {
print("Error reading file: \(error.localizedDescription)"
}