2014-03-19 90 views
2

我試圖壓縮一個文件到流,通過wcf發送和解壓縮。但是,使用下面的代碼,我在嘗試執行解壓縮的exe文件時得不到有效的exe文件。任何解壓縮的exe文件大約比原文低211-212字節。壓縮到流

Sub Main() 

    Dim strm As Stream = CompressToStream("c:\rje\Launcher.exe") 

    DecompressToFile(strm) 

End Sub 

壓縮例程

Private Function CompressToStream(ByVal strFullFilename As String) As Stream 

    If File.Exists(strFullFilename) Then 

     Dim uncompressedfile As New MemoryStream(File.ReadAllBytes(strFullFilename)) 

     Dim compressedStream As New MemoryStream 
     Dim compressionStream As New GZipStream(compressedStream, CompressionMode.Compress) 

     uncompressedfile.CopyToStream(compressionStream) 
     compressionStream.Flush() 
     compressedStream.Position = 0 
     Return compressedStream 

    End If 

    Return Nothing 
End Function 

擴展方法複製流作爲使用.NET3.5

<System.Runtime.CompilerServices.Extension()> _ 
Private Sub CopyToStream(ByVal input As Stream, ByRef output As Stream) 

    Dim Buffer(4096) As Byte 
    Dim numRead As Integer = input.Read(Buffer, 0, Buffer.Length) 
    Do While numRead <> 0 
     output.Write(Buffer, 0, numRead) 
     numRead = input.Read(Buffer, 0, Buffer.Length) 
    Loop 
End Sub 

最後減壓

Private Sub DecompressToFile(ByVal strmDownload As Stream) 

    Dim spath As String = "c:\rje\text.exe" 

    Using outFile As FileStream = File.Create(spath) 
     Using Decompress As GZipStream = New GZipStream(strmDownload, CompressionMode.Decompress) 
      ' Copy the compressed file into the decompression stream. 

      Dim buffer(4096) As Byte 
      Dim numRead As Integer = Decompress.Read(buffer, 0, buffer.Length) 
      Do While numRead <> 0 
       outFile.Write(buffer, 0, numRead) 
       numRead = Decompress.Read(buffer, 0, buffer.Length) 
      Loop 
     End Using 
     outFile.Close() 
    End Using 
End Sub 

如果有人能指出我哪裏「M出錯了,那會很好。

+1

切勿使用File.Exists()這樣的(第二代碼片段)。試着打開文件,如果失敗則處理異常。 –

+0

什麼版本的.Net? –

+0

@JoelCoehoorn 3.5 vs2008,爲什麼我不應該使用File.Exists()? – robpws

回答

2

錯誤是與CompressToStream,修改爲正確如下功能

Private Function CompressToStream(ByVal strFullFilename As String) As Stream 

    If File.Exists(strFullFilename) Then 
     Dim compressedStream As New MemoryStream() 
     Using uncompressedfile As New MemoryStream(File.ReadAllBytes(strFullFilename)) 
      Using compressionStream As New GZipStream(compressedStream, CompressionMode.Compress, True) 
       uncompressedfile.CopyToStream(compressionStream) 
      End Using 
     End Using 
     compressedStream.Seek(0, SeekOrigin.Begin) 
     Return compressedStream 
    End If 

    Return Nothing 
End Function 

我還沒有一個答案,爲什麼我不應該使用File.Exists()?

+2

File.Exists()只檢查是否存在,它不檢查權限,文件被anoth鎖定呃進程,還是文件的狀態在檢查和使用文件之間的簡短空間中發生了變化。 (文件系統是不穩定的,以這種方式使用File.Exists()會創建一個競爭條件,即使它很小)。所有這一切的結果是,無論如何你必須處理這個異常,使得.Exists()檢查在代碼維護方面是多餘的,並且浪費了一些額外的硬盤空間(關於最慢的事情一臺電腦可以做)。 –

+0

@JoelCoehoorn感謝您的解釋 – robpws

0

以下是改編自於我張貼在我的評論鏈接樣本壓縮()/解壓縮()方法:

Private Function Compress(ByVal strFullFilename As FileInfo) As Stream 
    ' Get the stream of the source file. 
    Dim fi as New FileInfo(strFullFilename) 
    Dim result As New MemoryStream() 
    Using inFile As FileStream = fi.OpenRead() 
     ' Compressing: 
     ' Prevent compressing hidden and already compressed files. 

     If (File.GetAttributes(fi.FullName) And FileAttributes.Hidden) _ 
      <> FileAttributes.Hidden And fi.Extension <> ".gz" Then 
      ' Create the compressed file. 
      Using Compress As GZipStream = New GZipStream(result, CompressionMode.Compress) 
       ' Copy the source file into the compression stream. 
       Dim buffer As Byte() = New Byte(4096) {} 
       Dim numRead As Integer = inFile.Read(buffer, 0, buffer.Length) 
       Do While numRead <> 0 
        Compress.Write(buffer, 0, numRead) 
        numRead = inFile.Read(buffer, 0, buffer.Length) 
       Loop 

       'Console.WriteLine("Compressed {0} from {1} to {2} bytes.", fi.Name, fi.Length.ToString(), result.Length.ToString()) 

      End Using 
     End If 
    End Using 
    Return result 
End Sub 

' Method to decompress. 
Private Sub Decompress(ByVal strmDownload As Stream, ByVal resultFileName As String)   

     ' Create the decompressed file. 
     Using outFile As FileStream = File.Create(resultFileName) 
      Using Decomp As GZipStream = New GZipStream(strmDownload, CompressionMode.Decompress) 
       ' Copy the compressed file into the decompression stream. 
       Dim buffer As Byte() = New Byte(4096) {} 
       Dim numRead As Integer = Decompress.Read(buffer, 0, buffer.Length) 

       Do While numRead <> 0 
        outFile.Write(buffer, 0, numRead) 
        numRead = Decomp.Read(buffer, 0, buffer.Length) 
       Loop 
       'Console.WriteLine("Decompressed: {0}", fi.Name) 

      End Using 
     End Using 
    End Using 
End Sub 
+0

我敢肯定,將返回一個封閉的流,因爲'最終使用'的壓縮將關閉流使其不可用 – robpws