Im following the steps described below to read csv but get runtime error at the last line.
(TypeInitializationException)
Can anyone tell me what's wrong here?
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
John's comment is on track, you're probably trying to read a file that doesn't exist.
In Windows, backslash is used for path separation, not (forward) slash.
These backslashes need to be escaped in an F# string literal.
The reason why you're seeing this as TypeInitializationException
is that this code is executed when the type is loaded. Had it been in a function, it would execute when called instead, and you would get the expected exception.
There are several ways of escaping the backslashes, pick one:
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""")
That last one, triple-quoting, is part of F# 3.0. http://blogs.msdn.com/b/fsharpteam/archive/2012/07/19/more-about-fsharp-3.0-language-features.aspx
Edit Your real error is obscured by the fact that your code runs in type initialization. Try structuring your code differently:
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
Now, instead of TypeInitializationException
we get a BadUsageException
with the message "The record class CsvRecord need a constructor with no args (public or private)". Much more useful! Fixing that, the code works as expected:
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