我正在尝试向FSharp.Data的Http模块(https://github.com/fsharp/FSharp.Data/blob/master/src/Library/Http.fs)添加一个功能,以下载并保存文件(来自Web响应流)。我修改了函数asyncReadToEnd但是出现了以下错误。什么是定义函数asyncReadToEnd
的最佳方式,因此如果未提供MemoryStream
,它将写入streamWriter
。
Error 1 This expression was expected to have type MemoryStream but here has type StreamWriter
错误行。 (在Some sw
)
use sw = new StreamWriter(fileName)
let! response = Http.InnerRequest(url, true, ?headers=headers, ?query=query, ?meth=meth, ?body=body, ?cookies=cookies, ?cookieContainer=cookieContainer, ?certificate=certificate, ?streamWriter=Some sw)
代码段:
/// Read the contents of a stream asynchronously and return it as a string
static let asyncReadToEnd (stream:Stream) isText streamWriter = async {
// Allocate 4kb buffer for downloading dat
let buffer = Array.zeroCreate (4 * 1024)
use output =
match streamWriter with
| Some (sw) -> sw
| None -> new MemoryStream()
let reading = ref true
....
static member private InnerRequest(url:string, forceText, ?query, ?headers, ?meth, ?body, ?cookies, ?cookieContainer, ?certificate, ?streamWriter) = async {
....
return! Http.augmentWebExceptionsWithDetails <| fun () -> async {
use! resp = Async.FromBeginEnd(req.BeginGetResponse, req.EndGetResponse)
use stream = resp.GetResponseStream()
let! respBody = asyncReadToEnd stream (forceText || (isText resp.ContentType)) streamWriter
let cookies = Map.ofList [ for cookie in cookieContainer.GetCookies uri |> Seq.cast<Cookie> -> cookie.Name, cookie.Value ]
let headers = Map.ofList [ for header in resp.Headers.AllKeys -> header, resp.Headers.[header] ]
let statusCode =
match resp with
| :? HttpWebResponse as resp -> int resp.StatusCode
| _ -> 0
return { Body = respBody
Headers = headers
ResponseUrl = resp.ResponseUri.OriginalString
Cookies = cookies
StatusCode = statusCode } }
}
static member AsyncRequestFile(url, (fileName:string), ?query, ?headers, ?meth, ?body, ?cookies, ?cookieContainer, ?certificate) = async {
use sw = new StreamWriter(fileName)
let! response = Http.InnerRequest(url, true, ?headers=headers, ?query=query, ?meth=meth, ?body=body, ?cookies=cookies, ?cookieContainer=cookieContainer, ?certificate=certificate, ?streamWriter=Some sw)
return
match response.Body with
| ResponseBody.Text text -> text
| ResponseBody.Binary binary -> failwithf "Expecting text, but got a binary response (%d bytes)" binary.Length
}
答案 0 :(得分:2)
问题似乎在于:
use output =
match streamWriter with
| Some (sw) -> sw
| None -> new MemoryStream()
streamWriter
被推断为MemoryStream option
因此streamWriter
的{{1}}参数也是如此。
当您在InnerRequest
中调用它时,您正在传递AsyncRequestFile
,因此错误。