簡體   English   中英

在F#中使用FileHelperAsyncEngine

[英]Using FileHelperAsyncEngine in F#

我試圖使用FileHelpers讀取csv將csv文件中的行加載到f#中的Elasticsearch數據庫中。 一切都適用於小型測試文件,下面的代碼片段可一次讀取所有記錄

let readRows<'T>(filePath:string) =
    let engine = FileHelperEngine(typeof<'T>)

    engine.ReadFile(filePath)
    |> Array.map (fun row -> row :?> 'T)

不幸的是,它需要能夠讀取較大的文件,以后會逐行丟棄其中的許多列。 函數FileHelperAsyncEngine.BeginReadFile返回一個IDisposable。

let readRowsAsync<'T>(filePath:string) =
    let engine = new FileHelperAsyncEngine(typeof<'T>)

    engine.BeginReadFile(filePath:string)
    |> ...

如何進一步將此對象處理為<'T> s數組?

根據文檔 ,調用BeginReadFileengine本身將成為可枚舉的序列,您可以在該序列上進行迭代(這是一個非常奇怪的設計決策)。 因此,您可以在其之上構建自己的序列:

let readRowsAsync<'T>(filePath:string) = 
  seq {
    let engine = new FileHelperAsyncEngine(typeof<'T>)
    use disposable = engine.BeginReadFile(filePath)

    for r in engine do
      if not (shouldDiscard r) then yield (map r)
  }

請注意,我使用的是use綁定,而不是let 這將確保在序列結束后一次性用品被丟棄,或者消費者停止在其上進行迭代。

請注意,即使編譯以下內容,它也不會起作用:

let readRowsAsync<'T>(filePath:string) = 
  let engine = new FileHelperAsyncEngine(typeof<'T>)
  use disposable = engine.BeginReadFile(filePath)

  engine |> Seq.filter (not << shouldDiscard) |> Seq.map map

如果以這種方式進行操作,則在函數返回之后但在對結果枚舉進行迭代之前,將丟棄一次性文件,從而在其時間之前關閉文件。 為確保一次性用品正確處置,您必須將整個物件括在seq表達式中。

如果您確實想使用Seq.filter / Seq.map而不是for / yield ,您仍然可以在seq表達式中執行seq

let readRowsAsync<'T>(filePath:string) = 
  seq {
    let engine = new FileHelperAsyncEngine(typeof<'T>)
    use disposable = engine.BeginReadFile(filePath)

    yield! engine |> Seq.filter (not << shouldDiscard) |> Seq.map map
  }

您還可以將過濾和映射帶出seq表達式(這會使您的函數更可重用),但是seq表達式本身必須保留在原處,因為它控制着處理部分:

let readRowsAsync<'T>(filePath:string) = 
  seq {
    let engine = new FileHelperAsyncEngine(typeof<'T>)
    use disposable = engine.BeginReadFile(filePath)

    yield! engine
  }

let results = 
  readRowsAsync<SomeType>( "someFile.txt" )
  |> Seq.filter (not << shouldDiscard) 
  |> Seq.map map

最后,必須注意,您應該小心處理此序列,因為它會占用非托管資源(即打開的文件):不要長時間保持打開狀態,在處理它時不要使用阻塞操作,等等

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM