F# CSV FileHelpers

Я выполняю шаги, описанные ниже, чтобы прочитать csv, но получаю ошибку времени выполнения в последней строке.
(TypeInitializationException)
Кто-нибудь может сказать мне, что здесь не так?

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  

person Chris    schedule 21.12.2012    source источник
comment
Путь, вероятно, должен быть строкой @ - @"C:/Users/...", иначе / интерпретируются как escape-символы. Ошибка, вероятно, открывает несуществующий файл   -  person John Palmer    schedule 21.12.2012
comment
Экранирующий символ — «\», а не «/».   -  person MiMo    schedule 21.12.2012


Ответы (1)


Комментарий Джона выполняется, вы, вероятно, пытаетесь прочитать несуществующий файл. В 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
person Robert Jeppesen    schedule 21.12.2012
comment
Пробовал let res = engine.ReadFile(D:\\test1.csv) и let res = engine.ReadFile(@D:\test1.csv), оба по-прежнему дают одно и то же исключение, а третий не компилируется. - person Chris; 22.12.2012
comment
@chris Обновил ответ. - person Robert Jeppesen; 22.12.2012
comment
Этот код работает идеально. Большое спасибо за помощь!! Кстати, любопытно, как люди отлаживают ошибки времени выполнения в F #. Я чувствую, что отладка кода F# — это боль из-за меньшего количества доступной информации. - person Chris; 22.12.2012