Преобразование в и из 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)