重置 StreamReader F#

Resetting StreamReader F#

我使用以下方法从 GET 请求下载数据:

let fetchUrl callback url =      
    let req = WebRequest.Create(Uri(url)) 
    req.Method <- "GET"
    use resp = req.GetResponse() 
    use stream = resp.GetResponseStream() 
    use reader = new IO.StreamReader(stream) 
    callback reader url

接下来我有一个使用 reader 的回调,如下所示:

 let myCallbackGetListings (reader:IO.StreamReader) url (chatMatch : ChatMatch) = 
    let html = reader.ReadToEnd()

我第一次使用它时效果很好,但是第二次,它就崩溃了:

let html = reader.ReadToEnd()

例外情况:

Cannot read from a closed TextReader.

我试过:

reader.BaseStream.Position <- (0 |> int64)
reader.DiscardBufferedData()

然而,这也不起作用并抛出异常:

Specified method is not supported.

在线尝试重置 BaseStream 位置。

并非总是可以设置流的位置。在这种特殊情况下,您的流来自网络,一旦您将其读入,除了要求远程发射器重复传输之外,没有办法 "repeat" 该过程。数据不是 "stored" 某个地方,比如磁盘或类似的东西,它在您阅读时来自网络。

我建议您更改应用程序架构,以便将数据存储在中间缓冲区中,以防需要多次读取,例如:

let fetchUrl callback url =      
    let req = WebRequest.Create(Uri(url)) 
    req.Method <- "GET"
    use resp = req.GetResponse() 
    use stream = resp.GetResponseStream() 
    let text = new IO.StreamReader(stream).ReadToEnd()
    callback (fun () -> new StringReader(text)) url

let myCallbackGetListings (getReader : unit -> TextReader) url (chatMatch : ChatMatch) = 
    let html = getReader().ReadToEnd()

在上面的代码中,我假设您确实出于某种目的确实需要 reader,但如果您只需要文本,您可以更简单:

let fetchUrl callback url =      
    ...
    let text = new IO.StreamReader(stream).ReadToEnd()
    callback text url

let myCallbackGetListings text url (chatMatch : ChatMatch) = 
    let html = text