Преобразование в и из Base64 в Powershell 5.1

Я нашел несколько ресурсов (в том числе преобразовать строку base64 в файл , которая здесь практически дублируется, поскольку это один из ресурсов, которые я использовал для ее создания), но я не могу заставить ее работать.

У меня есть следующий код (примерно - очевидно, он урезан), и я могу проверить большинство шагов процесса в соответствии с комментариями.

      $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 в некоторой степени важен (поскольку я храню данные в сценарии).

1 ответ

Чтобы прочитать двоичный файл как есть в памяти в PowerShell, используйте Get-Contentс -AsByteStreamпереключатель (PowerShell (Core) 7+) /(Windows PowerShell, версии до 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)
Другие вопросы по тегам