powershell 处理二进制数据流的核心是绕过文本编码干扰、直接操作字节序列,依托 .net 的 filestream 和 memorystream 实现精准低损操作,避免 get-content/set-content 的文本陷阱,并通过分块流式处理保障大文件内存安全。
powershell 在 windows 环境下处理二进制数据流,核心在于绕过文本编码干扰、直接操作字节序列,并确保跨工具链(如 clipboardy、文件切割、模块加载)中数据的完整性。它不依赖字符串解析,而是依托 .net 的 io 类型和原生命令能力,实现精准、低损的二进制操作。
用 FileStream 和 MemoryStream 直接读写字节
PowerShell 调用 .NET 的 System.IO.FileStream 和 System.IO.MemoryStream 是最可靠的方式。它们跳过默认的文本解码逻辑,避免换行符转换、BOM 插入或 Unicode 截断等问题。- 创建只读 FileStream:
$fs = [System.IO.FileStream]::new("input.bin", "Open", "Read", "None") - 读取全部字节到内存:
$bytes = New-Object byte[] $fs.Length; $null = $fs.Read($bytes, 0, $bytes.Length); $fs.Close() - 修改指定偏移处的字节(例如将第 100 字节设为 0xFF):
$bytes[99] = 0xFF - 写回新文件:
[System.IO.File]::WriteAllBytes("output.bin", $bytes)
避免 Get-Content / Set-Content 的文本陷阱
Get-Content 和 Set-Content 默认按文本处理,即使加 `-Encoding Byte` 也仅在 PowerShell 5.1+ 中可用,且在旧版本或管道中易出错。更稳妥的做法是:
- 不要用:
Get-Content file.exe -Encoding Byte(兼容性差,部分场景返回对象而非纯字节数组) - 改用:
[System.IO.File]::ReadAllBytes("file.exe")(稳定、返回[byte[]]) - 写入时同理,优先用:
[System.IO.File]::WriteAllBytes("out.exe", $bytes)
在剪贴板与网络传输中保持二进制语义
clipboardy 的 PowerShell 实现之所以可靠,是因为它显式设置[Console]::InputEncoding = [System.Text.Encoding]::UTF8 并用 MemoryStream 拷贝原始输入流——这保证了粘贴文本时不会因控制字符或零字节丢失而中断。
- 复制二进制内容(如 Base64 编码后的 payload)时,应先转为字节数组再送入剪贴板:
[System.Windows.Forms.Clipboard]::SetDataObject([System.Text.Encoding]::UTF8.GetBytes("data")) - 若需通过 PowerShell 向远程 Linux 传二进制块(如分片上传),务必禁用 FTP 的 ASCII 模式,FileZilla 中需手动设为 Binary 模式,否则
0x0D 0x0A会被错误替换。
处理大文件时的内存与流控策略
直接加载几十 GB 文件到内存会崩溃。正确做法是分块流式处理:- 使用缓冲区逐块读写(推荐 1–4 MB 块):
$buffer = New-Object byte[] 1MB; while (($read = $fs.Read($buffer, 0, $buffer.Length)) -gt 0) { ... } - 结合
System.IO.BufferedStream提升吞吐:$bs = [System.IO.BufferedStream]::new($fs, 64KB) - 避免在管道中传递整个字节数组,改用
Write-Output -NoEnumerate或直接写文件
不复杂但容易忽略











