2017-09-03 139 views
2

作爲F#培訓,我試圖解壓gzip文件。這是我寫的代碼:異步解壓縮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 capablib的一個,但我看不到我的錯誤...

回答

4

您對Async的使用非常好。你只有一個MemoryStream,其位置仍然在寫入之後,所以沒有任何可讀的。在創建StreamReader之前,請使用以下方法來重置位置,它將起作用:

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