Я бачу, що багато з цих відповідей покладаються на те, щоб прочитати весь текстовий файл в пам'яті, а не брати його по черзі. Ось моє рішення в приємному сучасному Swift, використовуючи FileHandle для зменшення впливу пам'яті:
enum MyError {
case invalidTextFormat
}
extension FileHandle {
func readLine(maxLength: Int) throws -> String {
// Read in a string of up to the maximum length
let offset = offsetInFile
let data = readData(ofLength: maxLength)
guard let string = String(data: data, encoding: .utf8) else {
throw MyError.invalidTextFormat
}
// Check for carriage returns; if none, this is the whole string
let substring: String
if let subindex = string.firstIndex(of: "\n") {
substring = String(string[string.startIndex ... subindex])
} else {
substring = string
}
// Wind back to the correct offset so that we don't miss any lines
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)
// Do something with the string here
}
try handle.close()
catch let error {
print("Error reading file: \(error.localizedDescription)"
}