2014-03-19 138 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