Сжатие в поток
Я пытаюсь сжать файл в поток, который отправляется через 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
Если бы кто-то мог указать, где я иду не так, это было бы здорово.
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()?
Вот адаптированные методы Compress()/Decompress() из примера в ссылке, которую я разместил в своем комментарии:
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