异步解压缩gzip文件

时间:2017-09-03 18:06:31

标签: f#

作为F#培训,我试图解压缩gzip文件。这是我写的代码:

let decompress (inputStream: Stream) (outputStream : Stream) = async {
    use gs = new GZipStream(inputStream, CompressionMode.Decompress)
    let buffer = Array.zeroCreate<byte> 4096

    let rec decompressInternal() = async {
        let! read = gs.ReadAsync(buffer, 0, buffer.Length) |> Async.AwaitTask
        match read with
        | 0 ->
            inputStream.Dispose()
            return ()
        | _ ->
            do! outputStream.WriteAsync(buffer, 0, read) |> Async.AwaitTask |> Async.Ignore
            return! decompressInternal()
    }

    return! decompressInternal()
}

我还写了一个单元测试,暂时失败了(我得到一个空字符串,好像在解压缩操作后发生了断言):

[<Fact>]
let ``Decompress a gzipped file`` () =
    use fs = new FileStream("Input/test.txt.gz", FileMode.Open)
    use ms = new MemoryStream()
    decompress fs ms |> Async.RunSynchronously
    use sr = new StreamReader(ms)
    Assert.Equal ("This is a test", sr.ReadToEnd())

我想我误解了其中一个F#async capablibilites,但我看不出我的错误......

1 个答案:

答案 0 :(得分:4)

您对Async的使用非常好。你只有一个MemoryStream,其位置仍然在写入之后,因此没有什么可以从那里读取的。在创建StreamReader之前使用以下内容重置位置,它将起作用:

ms.Seek(0L, SeekOrigin.Begin) |> ignore