2016-08-28 22 views
1

大容量のcsvファイルを使用すると、非常に効率的な方法で最後の行を読み取ることができますか?私はこれをよく行う次のPython関数を持っています。同等のF#解があるかどうかわかりません。大容量のcsvファイルから最後の行を効率的に読み取る

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 

[EDIT] どのように私は行末文字を検出し、次の行を返すことができるように、第2の最後の行にあることをバックだけで十分なバイトをジャンプして把握するのと、私はまだわかりませんよ。 -100Lはcsv(何千もある)に応じて元に戻す正しい量ではないかもしれません。

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() 
+1

確かに、あなたはF#で丁度良いものを探すことができます。 'System.IO.File.Open'を見てください。 –

+1

関連する、潜在的な回答が埋め込まれている:http://stackoverflow.com/q/34227084/126014 –

答えて

3

これが動作しているようですが、ファイルはASCIIまたはUTF-7であると仮定して、ラインを分離するために、単一の改行文字がありますし、ファイルが改行で終わります。

これは本当に慣習的なスタイルではありません。

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 
関連する問題