I can convert files to B64 then back again, i would like to compress the data before converting to B64. Gzip doesnt have to be used, any type of compression or size reduction is fine, I think compression is the answer if I can get it somewhere in the conversion process because B64 uses more space than the original file when stored.

Current situation: File -> B64 + B64 -> File (Working fine with no temp files)

Goal: File->Compression->B64 + B64->Decompression->File (With no temp files)

Working non compressed example

FileToB64Text.ps1

[Convert]::ToBase64String([IO.File]::ReadAllBytes('test.pdf')) | Out-File 'testpdf.txt"

B64TextToFile.ps1

$file = Get-Content 'testpdf.txt'
[IO.File]::WriteAllBytes('test2.pdf', [Convert]::FromBase64String('$file'))

I stumbled across another way to do this with compression, which seems great since B64 conversion increases filesize, but the example is using TextToB64/B64ToText instead of FilesToB64/B64ToFiles. A way to use files as an initial input and final output AND having the compression is what I am trying to achieve.

CompressAndEncode.ps1

$s = Get-Content 'DecodedText.txt'
$ms = New-Object System.IO.MemoryStream
$cs = New-Object System.IO.Compression.GZipStream($ms, [System.IO.Compression.CompressionMode]::Compress)
$sw = New-Object System.IO.StreamWriter($cs)
$sw.Write($s)
$sw.Close();
$s = [System.Convert]::ToBase64String($ms.ToArray()) | Out-File 'b64output.txt'

DecodeAndDecompress.ps1

$encodedstring = Get-Content 'b64output.txt'
$data = [System.Convert]::FromBase64String("$encodedstring")
$ms = New-Object System.IO.MemoryStream
$ms.Write($data, 0, $data.Length)
$ms.Seek(0,0) | Out-Null
$sr = New-Object System.IO.StreamReader(New-Object System.IO.Compression.GZipStream($ms, [System.IO.Compression.CompressionMode]::Decompress))
$sr.ReadToEnd() | Out-File 'DecodedText.txt
1

There are 1 best solutions below

10
Santiago Squarzon On BEST ANSWER

The main idea is that if you're gzipping to a file you shouldn't convert the compressed bytes to b64, there is no need for that and would only increase the file size for no reason as b64 is used mainly for transport of information.

  • If you want to Gzip compress to a file:
$infile = Get-Item path\to\myfiletocompress.ext
$instream = $infile.OpenRead()
$outstream = (New-Item path\to\mygzfile.gz).OpenWrite()
$gzip = [System.IO.Compression.GZipStream]::new(
    $outstream,
    [System.IO.Compression.CompressionLevel]::Optimal)
$instream.CopyTo($gzip)

$gzip.Dispose()
$outstream.Dispose()
$instream.Dispose()
  • If you want to expand a Gzip file:
$infile = Get-Item path\to\mygzfile.gz
$instream = $infile.OpenRead()
$outstream = (New-Item path\to\myexpandedgzfile.ext -Force).OpenWrite()
$gzip = [System.IO.Compression.GZipStream]::new(
    $instream,
    [System.IO.Compression.CompressionMode]::Decompress)
$gzip.CopyTo($outstream)

$gzip.Dispose()
$outstream.Dispose()
$instream.Dispose()
  • If you want to read the Gzip file content:
$infile = Get-Item mygzfile.gz
$instream = $infile.OpenRead()
$gzip = [System.IO.Compression.GZipStream]::new(
    $instream,
    [System.IO.Compression.CompressionMode]::Decompress)
$reader = [System.IO.StreamReader] $gzip
$reader.ReadToEnd()

$gzip.Dispose()
$reader.Dispose()
$instream.Dispose()
  • If you have a gzip b64 string in a file and you want to read its content:
$instream = [System.IO.MemoryStream]::new(
    [System.Convert]::FromBase64String((Get-Content .\mygzfile.gz -Raw)))
$gzip = [System.IO.Compression.GZipStream]::new(
    $instream,
    [System.IO.Compression.CompressionMode]::Decompress)
$outstream = [System.IO.MemoryStream]::new()
$gzip.CopyTo($outstream)

$gzip.Dispose()
$instream.Dispose()

$outstream.Seek(0, [System.IO.SeekOrigin]::Begin)
$reader = [System.IO.StreamReader] $outstream
$reader.ReadToEnd()

$reader.Dispose()
$outstream.Dispose()

If you would like to simplify this process, you can give PSCompression a try:

# compression
Compress-GZipArchive path\to\filetocompress path\to\destination.gz

# expansion to the success stream
Expand-GzipArchive path\to\compressed.gz

# expansion to a file
Expand-GzipArchive path\to\compressed.gz path\to\expanded

# expansion of gzip b64 string
Get-Content path\to\compressed.gz | ConvertFrom-GzipString