2012-12-21 27 views
1

我按照下面介紹的步驟閱讀csv,但在最後一行得到運行時錯誤。
(TypeInitializationException)
誰能告訴我這裏有什麼問題嗎?F#CSV FileHelpers

http://www.markstaples.com/2009/01/08/parsing-csv-files-in-f/

module ReadCsv //------------------------------------- 
open System 
open FileHelpers 
[<DelimitedRecord(",")>] 
[<IgnoreFirst(1)>] 
type CsvRecord = 
    class 
     val field1 : string 
    end 

type oneRow() = 
    class 
     [<DefaultValue>] 
     val mutable Str1: string 
     [<DefaultValue>] 
     val mutable Str2: string 
    end 

let engine = new FileHelperEngine(typeof<CsvRecord>) 
let res = engine.ReadFile("C:/Users/Admin/Desktop/test.csv") 

module main //-------------------------------- 
let downcast_Customer_Array = Array.map (fun (a:obj) -> a :?> ReadCsv.CsvRecord) 
let res_Customers = downcast_Customer_Array ReadCsv.res 
+0

的路徑也許應該是一個'@'字符串 - '@ 「C:/用戶/ ...」',否則'/'被解釋爲轉義字符。錯誤可能是打開一個不存在的文件 –

+1

轉義字符是'\',而不是'/' – MiMo

回答

2

約翰的評論的軌道上,你可能會試圖讀取一個不存在的文件。 在Windows中,反斜槓用於路徑分離,而不是(前向)斜槓。 這些反斜槓需要在F#字符串文字中轉義。 您看到這個爲TypeInitializationException的原因是該代碼在加載類型時執行。如果它在函數中,它會在調用時執行,而您會得到預期的異常。

有逃避反斜槓的幾種方法,選擇一個:

let res = engine.ReadFile("C:\\Users\\Admin\\Desktop\\test.csv") 
let res = engine.ReadFile(@"C:\Users\Admin\Desktop\test.csv") 
let res = engine.ReadFile("""C:\Users\Admin\Desktop\test.csv""") 

這最後一個,三報價,是F#3.0的一部分。 http://blogs.msdn.com/b/fsharpteam/archive/2012/07/19/more-about-fsharp-3.0-language-features.aspx

編輯 真實錯誤是由你的代碼類型初始化運行的事實掩蓋。嘗試不同的構建代碼:

module ReadCsv = //------------------------------------- 
    open System 
    open FileHelpers 

    [<DelimitedRecord(",")>] 
    [<IgnoreFirst(1)>] 
    type CsvRecord = 
     class 
      val field1 : string 
     end 

    let read file = 
     let engine = new FileHelperEngine(typeof<CsvRecord>) 
     engine.ReadFile(file) 
     |> Array.map (fun row -> row :?> CsvRecord) 

module Main = //-------------------------------- 
    [<EntryPoint>] 
    let main argv = 
     let results = ReadCsv.read "C:/Users/Admin/Desktop/test.csv" 
     printfn "%A" results 
     0 // return an integer exit code 

現在,而不是TypeInitializationException我們得到一個BadUsageException消息「的記錄類CsvRecord需要無參數(公共或私人)構造」。更有用!固定的是,該代碼按預期工作:

module ReadCsv = //------------------------------------- 
    open System 
    open FileHelpers 

    [<DelimitedRecord(",")>] 
    [<IgnoreFirst(1)>] 
    type CsvRecord() = 
     class 
      [<DefaultValue>] 
      val mutable field1 : string 
     end 

    let read file = 
     let engine = new FileHelperEngine(typeof<CsvRecord>) 
     engine.ReadFile(file) 
     |> Array.map (fun row -> row :?> CsvRecord) 

module Main = //-------------------------------- 
    [<EntryPoint>] 
    let main argv = 
     let results = ReadCsv.read "C:/Users/Admin/Desktop/test.csv" 
     results |> Seq.iter (fun r -> printfn "%s" r.field1) 
     0 // return an integer exit code 
+0

嘗試 let res = engine.ReadFile(「D:\\ test1.csv」)and let res = engine.ReadFile(@「D:\ test1.csv」) 兩者仍然給出相同的異常,並且第三個 fails編譯。 – Chris

+0

@chris更新了答案。 –

+0

該代碼完美無缺。非常感謝你的幫助!! btw,好奇人們如何在F#中調試運行時錯誤。我覺得調試 由於信息的可用性較低,F#代碼很痛苦。 – Chris