在F#中正确处理流

时间:2015-02-06 23:50:56

标签: io f# idisposable

以下代码在从文件读取时抛出ObjectDisposedException。在枚举整个序列之前,似乎BinaryReader超出了范围。在不泄漏读卡器的情况下,安全地拨打电话的正确方法是什么?我不想在顶级代码中进行流管理 - 理想情况是在给定文件路径时隐藏。

在此代码中,Edge.ReadBinary执行从二进制流反序列化Edge的明显任务。在我的代码中,文件夹做了一些更复杂的事情,但为了便于阅读,我在这里进行了简化。

let rec readEdges (br:BinaryReader) =
    seq {
        match Edge.ReadBinary br with
        | None -> yield! Seq.empty  
        | Some(e) -> yield e; yield! readEdges br        
    }

let readBinaryEdges fn =
    use br=new BinaryReader(File.OpenRead(fn))
    readEdges br

let sampled=readBinaryEdges fn |> Seq.fold (fun result l -> l::result) list.Empty 

1 个答案:

答案 0 :(得分:4)

正如iljdarn的评论所指出的,将use置于序列表达式中可以解决这个问题。这是有效的,因为序列表达式构建器为use关键字定义了自己的语义,以便在适当的时候支持处理。因此,如果您将功能更改为

let readBinaryEdges fn =
    seq { use br = new BinaryReader(File.OpenRead(fn))
          yield! readEdges br }

读者将按顺序处理。