2012-12-21 24 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