Hi @StewartBW ,
You can first create a temporary directory, then compress each file individually into that directory, and finally compress the directory itself into a single .gz
file.
And to ensure that the extracted files retain their original names and content, you need to store that information during compression and restore it during extraction.
Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
Dim file1 As String = "C:\Users\Administrator\Desktop\file1.txt"
Dim file2 As String = "C:\Users\Administrator\Desktop\file2.txt"
Dim compressedFile As String = "C:\Users\Administrator\Desktop\compressed_files.gz"
CompressFilesIntoGZip({file1, file2}, compressedFile)
End Sub
Private Sub Button4_Click(sender As Object, e As EventArgs) Handles Button4.Click
Dim compressedFile As String = "C:\Users\Administrator\Desktop\compressed_files.gz"
Dim outputDirectory As String = "C:\Users\Administrator\Desktop\extracted_files"
ExtractFilesFromGZip(compressedFile, outputDirectory)
End Sub
Private Sub CompressFilesIntoGZip(files As String(), compressedFile As String)
Using outputStream As FileStream = File.Create(compressedFile)
Using gzipStream As New GZipStream(outputStream, CompressionMode.Compress)
For Each f In files
Dim fileInfo As New FileInfo(f)
Dim fileSizeBytes As Long = fileInfo.Length
' Write file name and size to the compressed stream
Dim fileNameBytes() As Byte = Encoding.UTF8.GetBytes(fileInfo.Name)
gzipStream.Write(BitConverter.GetBytes(fileNameBytes.Length), 0, 4)
gzipStream.Write(fileNameBytes, 0, fileNameBytes.Length)
gzipStream.Write(BitConverter.GetBytes(fileSizeBytes), 0, 8)
' Write file content to the compressed stream
Using inputFileStream As FileStream = File.OpenRead(f)
inputFileStream.CopyTo(gzipStream)
End Using
Next
End Using
End Using
Console.WriteLine($"Files {String.Join(", ", files)} compressed into {compressedFile}")
End Sub
Private Sub ExtractFilesFromGZip(compressedFile As String, outputDirectory As String)
' Create a directory to extract files into
Directory.CreateDirectory(outputDirectory)
Using inputStream As FileStream = File.OpenRead(compressedFile)
Using gzipStream As New GZipStream(inputStream, CompressionMode.Decompress)
While True
' Read file name length
Dim fileNameLengthBuffer(3) As Byte
Dim bytesRead As Integer = gzipStream.Read(fileNameLengthBuffer, 0, 4)
If bytesRead = 0 Then Exit While
' Read file name
Dim fileNameLength As Integer = BitConverter.ToInt32(fileNameLengthBuffer, 0)
Dim fileNameBytes(fileNameLength - 1) As Byte
gzipStream.Read(fileNameBytes, 0, fileNameLength)
Dim fileName As String = Encoding.UTF8.GetString(fileNameBytes)
' Read file size
Dim fileSizeBuffer(7) As Byte
gzipStream.Read(fileSizeBuffer, 0, 8)
Dim fileSize As Long = BitConverter.ToInt64(fileSizeBuffer, 0)
' Create the output file path
Dim extractedFilePath As String = Path.Combine(outputDirectory, fileName)
' Write file content to the output file
Using outputFileStream As New FileStream(extractedFilePath, FileMode.Create, FileAccess.Write)
Dim buffer(4096) As Byte
Dim totalBytesRead As Integer = 0
While totalBytesRead < fileSize
Dim bytesToRead As Integer = Math.Min(buffer.Length, CInt(fileSize - totalBytesRead))
Dim bytesReadThisTime As Integer = gzipStream.Read(buffer, 0, bytesToRead)
If bytesReadThisTime = 0 Then Exit While
outputFileStream.Write(buffer, 0, bytesReadThisTime)
totalBytesRead += bytesReadThisTime
End While
End Using
End While
End Using
End Using
Console.WriteLine($"Files extracted from {compressedFile} to {outputDirectory}")
End Sub
Best Regards.
Jiachen Li
If the answer is helpful, please click "Accept Answer" and upvote it.
Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.