给定一个大的csv文件,是否可以以合理有效的方式读取最后一行?我有以下python函数,做得很好。想知道是否有相应的F#解决方案。
def readCsvLines(fp):
with open(fp, "rb") as f:
first = f.readline()
second = f.readline()
f.seek(-2, 2) # jump to the second last byte
while f.read(1) != "\n": # until EOL is found...
f.seek(-2, 1) # jump back the read byte plus one more
last = f.readline()
return first, second, last
[编辑] 我仍然不确定如何找出跳回到最后一行的足够字节,以便我可以检测行尾字符并返回下一行。根据csv(有数千个),-100L可能不是正确的跳回量。
open System.IO
let f = File.Open("someFile.txt", FileMode.Open)
f.Seek(-100L, SeekOrigin.End) |> ignore
let s = new StreamReader(f)
while s.Read() <> 10 do
ignore
let ln = s.ReadLine()
答案 0 :(得分:3)
这似乎有效,假设文件是ASCII或UTF-7,单个换行符分隔行,文件以换行符结束。
虽然这不是真正惯用的F#,但非常强制性。
let lastLine (path) =
use strm = new System.IO.FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, 2048, FileOptions.RandomAccess)
strm.Seek(-2L, SeekOrigin.End) |> ignore
while (strm.ReadByte() <> 0xa) do
strm.Seek(-2L, SeekOrigin.Current) |> ignore
use br = new BinaryReader(strm, System.Text.Encoding.UTF7)
br.ReadChars(int (strm.Length - strm.Position) - 1) // Remove the newline at the end of the file
|> System.String