首页 > 解决方案 > 在 Powershell 5.1 中与 Base64 相互转换

问题描述

我找到了一些资源(包括Convert base64 string to file,这里实际上是重复的,因为它是我用来构建它的资源之一),但我似乎无法让它工作。

我有以下代码(大致 - 显然它已被剥离),我可以根据评论验证该过程的大部分步骤。

$pic = Get-Content 'testpic.png'
# $pic looks like a binary dump.

$picBytes = [System.Text.Encoding]::Unicode.GetBytes($pic)
$ $picBytes is an array of bytes. Quite spammy.

$picEncoded = [Convert]::ToBase64String($picBytes)
# $picEncoded is indeed a Base64 string. Halfway there!

$picDecoded = [Convert]::FromBase64String($picEncoded)
# Also an array of bytes. I'm assuming they're right for now...

$outFile = "pic.png"
[IO.File]::WriteAllBytes($outFile,$picDecoded)
# but I get no output file and no error?

我在这里想念什么?对于它的价值,我愿意看看其他解决方案 - 但 Base64 有点重要(因为我将数据存储在脚本中。)

标签: powershellbase64powershell-5.1

解决方案


要在 PowerShell 中按原样将二进制Get-Content文件读入内存,请使用's -AsByteStreamswitch (PowerShell (Core) 7+) / -Encoding Byte(Windows PowerShell, version up to v5.1),并在读取所有内容时添加-Raw开关以提高效率字节一次进入内存:

# Windows PowerShell (up to v5.1).
# Note: In PowerShell (Core) v7+, you must use -AsByteStream instead of
#       -Encoding Byte
$picBytes = Get-Content testpic.png -Encoding Byte -Raw

注意:不幸的是,PowerShell 版本之间的这种语法变化,如GitHub 问题 #7986中所述。如果足够多的人表现出兴趣,可以想象-Encoding Byte为了跨版本的一致性和兼容性而重新引入。

$picBytes,作为一个[byte[]]数组,然后可以直接传递给[Convert]::ToBase64String()


要将文件名/路径传递给 .NET 方法,请始终传递完整路径,而不是相对路径或仅传递文件名:

这是必要的,因为.NET 的工作目录通常不同于 PowerShell 的.
这种差异是不幸的,但无法避免,正如这个答案中所解释的那样。

最简单的情况下- 如果您的当前位置是基于PowerShell 特定驱动器的文件系统位置:

$outFile = "$PWD/pic.png" # Use *full path*
[IO.File]::WriteAllBytes($outFile, $picDecoded)

完全稳健的方法需要更多的工作:

$outFile = Join-Path (Get-Location -PSProvider FileSystem).ProviderPath pic.png
[IO.File]::WriteAllBytes($outFile, $picDecoded)

推荐阅读