Как читать файл построчно в Юлии?

Как открыть текстовый файл и прочитать его построчно? Ответы на два вопроса мне интересны:

  1. Получить все строки в массиве сразу.
  2. Обрабатывайте каждую строку по одной за раз.

Во втором случае я не хочу хранить все строки в памяти одновременно.

Ответы

Ответ 1

Считывание файла в память одновременно в виде массива строк - это просто вызов функции readlines:

julia> words = readlines("/usr/share/dict/words")
235886-element Array{String,1}:
 "A"
 "a"
 "aa"
 ⋮
 "zythum"
 "Zyzomys"
 "Zyzzogeton"

По умолчанию это отбрасывает символы новой строки, но если вы хотите сохранить их, вы можете передать аргумент ключевого слова keep=true:

julia> words = readlines("/usr/share/dict/words", keep=true)
235886-element Array{String,1}:
 "A\n"
 "a\n"
 "aa\n"
 ⋮
 "zythum\n"
 "Zyzomys\n"
 "Zyzzogeton\n"

Если у вас уже есть открытый файловый объект, вы также можете передать его в функцию readlines:

julia> open("/usr/share/dict/words") do io
           readline(io) # throw out the first line
           readlines(io)
       end
235885-element Array{String,1}:
 "a"
 "aa"
 "aal"
 ⋮
 "zythum"
 "Zyzomys"
 "Zyzzogeton"

Здесь демонстрируется функция readline, которая читает одну строку из открытого объекта ввода-вывода или, когда ему присваивается имя файла, открывает файл и читает первую строку из него:

julia> readline("/usr/share/dict/words")
"A"

Если вы не хотите загружать содержимое файла сразу (или если вы обрабатываете потоковые данные, например, из сетевого сокета), то вы можете использовать функцию eachline, чтобы получить итератор, который выдает строки один за раз:

julia> for word in eachline("/usr/share/dict/words")
           if length(word) >= 24
               println(word)
           end
       end
formaldehydesulphoxylate
pathologicopsychological
scientificophilosophical
tetraiodophenolphthalein
thyroparathyroidectomize

Функция eachline, как и readlines, может также иметь дескриптор открытого файла для чтения строк из. Вы также можете "свернуть свой" итератор, открыв файл и неоднократно вызывая readline:

julia> open("/usr/share/dict/words") do io
           while !eof(io)
               word = readline(io)
               if length(word) >= 24
                   println(word)
               end
           end
       end
formaldehydesulphoxylate
pathologicopsychological
scientificophilosophical
tetraiodophenolphthalein
thyroparathyroidectomize

Это эквивалентно тому, что eachline делает для вас, и редко нужно делать это самостоятельно, но если вам нужно, способность есть. Дополнительную информацию о чтении файла символ за символом смотрите в следующем вопросе и ответе: Как мы используем julia для чтения каждого символа файла .txt, по одному за раз?