Я ищу, чтобы быстро получить только последнюю строку файла в Haskell --- начиная с конца, а не с начала --- и с некоторыми трудностями с помощью hSeek правильно.hSeek и SeekFromEnd в Haskell
Кажется, SeekFromEnd N
ведет себя иначе, чем найти длину файла sz
, и с помощью AbsoluteSeek
идти (sz - N)
байт.
outh <- openFile "test.csv" ReadMode
λ> hIsSeekable outh
True
λ> hFileSize outh
81619956
λ> hSeek outh AbsoluteSeek 1000
λ> hTell outh
1000
λ> hSeek outh SeekFromEnd 1000
λ> hTell outh
81620956
λ> hSeek outh AbsoluteSeek 0
λ> hGetLine outh
"here's my data"
λ> hSeek outh SeekFromEnd 10000
-*** Exception: test.csv: hGetLine: end of file
Хм, это странно.
Итак, я сделал функцию, которая делает это с абсолютной вместо:
λ> hSeek outh SeekFromEnd 100000
λ> hTell outh
81719956
fromEnd outh = do
sz <- hFileSize outh
hSeek outh AbsoluteSeek (sz - 100000)
λ> fromEnd outh
λ> hTell outh
81519956
Так выход мудрым, они имеют разные ответы, которые странно. Кроме того, теперь я могу также использовать hGetLine, который SeekFromEnd не удалось на:
λ> hGetLine outh
"partial output"
λ> hGetLine outh
"full output, lots of fields, partial output"
Не ясно мне, что здесь происходит. Почему мой fromEnd ведет себя иначе, чем SeekFromEnd в разрешении hGetLine?
Вопрос 2: что/будет/будет правильной стратегией для начала в конце файла и поиска назад к первой новой строке (первая \ n после новой строки EOF)?
В этом вопросе я ищу конкретный ответ, используя SeekFromEnd.
Кажется, что 'hSeek outh SeekFromEnd 1000' переместился на 1000 байт после окончания! Этого не должно быть. ["Невозможно установить отрицательную позицию ввода/вывода или физический файл, позицию ввода-вывода за пределами текущего конца файла."] (Http://hackage.haskell.org/package/ base-4.9.1.0/docs/System-IO.html # v: hSeek) Теперь я тоже смущен. В любом случае, я думаю, вы должны использовать offset -1000. – chi
А, я должен был использовать древнюю науку вычитания. Спасибо, @chi, даже не заметил этого. – Mittenchops
Возможный дубликат [Haskell Читать последнюю строку с ленивым mmap] (http://stackoverflow.com/questions/41656678/haskell-read-last-line-with-a-lazy-mmap) – Alec