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
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.
$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()
$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()
$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()
$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