在Powershell中,如何将二进制文件重定向到标准输入?

5

以下方法不适用于二进制文件:在Windows Powershell中重定向标准输入输出

以下是我正在使用的输入摘要。您可以看到ls显示该文件为858320字节,但通过Get-Content进行管道传输时并非如此。

PS C:\Users\Joseph\Documents\GitHub\java_hprof_to_txt> ls .\generate_hprof\heap.dump.hprof


    Directory: C:\Users\Joseph\Documents\GitHub\java_hprof_to_txt\generate_hprof


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----        1/28/2017  12:02 PM         858320 heap.dump.hprof

这是一个简单的测试程序,它可以统计标准输入中的字节数,直到读取到文件结束符为止:

#include <stdio.h>  
#include <fcntl.h>  
#include <io.h> 


int main()
{
    char buff;
    int numOfBytesRead;
    int dataLen = 0;

    #ifdef _WIN32
    int result = _setmode(_fileno(stdin), _O_BINARY);
    if (result == -1)
        perror("Cannot set mode");
    else
        printf("'stdin' successfully changed to binary mode\n");
    #endif

    while (true) {
        numOfBytesRead = fread(&buff, 1, 1, stdin);
        if (numOfBytesRead != 1) {
            if (feof(stdin)) {
                fprintf(stdout, "end of file reached\n");
            }
            int errorCode = ferror(stdin);
            if (errorCode) {
                fprintf(stdout, "error reading file %d\n", errorCode);
            }
            perror("The following error occurred:");
            break;
        }
        dataLen++;
    }
    fprintf(stdout, "read %d bytes\n", dataLen);
    return 0;
}

这是输出结果。请注意,字节与ls命令不匹配。
PS C:\Users\Joseph\Documents\GitHub\java_hprof_to_txt> Get-Content .\generate_hprof\heap.dump.hprof | .\x64\Debug\CountBytes.exe
'stdin' successfully changed to binary mode
end of file reached
The following error occurred:: No error
read 860183 bytes

我甚至尝试了-编码字节和-编码未知,但这并没有帮助:

PS C:\Users\Joseph\Documents\GitHub\java_hprof_to_txt> Get-Content -Encoding Byte  .\generate_hprof\heap.dump.hprof | .\x64\Debug\CountBytes.exe
'stdin' successfully changed to binary mode
end of file reached
The following error occurred:: No error
read 3253650 bytes

PS C:\Users\Joseph\Documents\GitHub\java_hprof_to_txt> Get-Content -Encoding Unknown  .\generate_hprof\heap.dump.hprof | .\x64\Debug\CountBytes.exe
'stdin' successfully changed to binary mode
end of file reached
The following error occurred:: No error
read 429608 bytes

当我在普通命令终端中运行它时,它正常工作:
C:\Users\Joseph\Documents\GitHub\java_hprof_to_txt>.\x64\Debug\CountBytes.exe <  .\generate_hprof\heap.dump.hprof
'stdin' successfully changed to binary mode
end of file reached
The following error occurred:: No error
read 858320 bytes

1
从文档中得知:"在读写二进制文件时,使用Byte作为Encoding动态参数的值,使用0作为ReadCount参数的值"。这能帮到您吗? - David Brabant
是的,我看到了,但我不想将整个文件内容加载到内存中,因为未来二进制文件可能很大。现在我会尝试这样做。我猜我的用例与PowerShell操作对象而不是流的哲学不一致。 - joseph
不要在低级操作中使用高级 cmdlets,而是使用 .NET 二进制读写器并直接访问 std 流,参见 Output binary data on powershell pipeline - wOxxOm
那篇文章是关于输出方面的。我对输入感到困惑,因为PowerShell不支持“<”。 - joseph
1
@joseph Get-Content 读取行并省略 CR/LF 字节。这适用于文本文件,因为结果将是一个字符串数组,每个字符串代表一行。要管道化原始数据(因此在此情况下是二进制数据),请向 Get-Content 添加 -Raw 开关。 - stackprotector
1个回答

6
如果添加-Raw参数没有帮助:
Get-Content .\generate_hprof\heap.dump.hprof -Raw | .\x64\Debug\CountBytes.exe

使用 Start-Process 命令很可靠:

Start-Process .\x64\Debug\CountBytes.exe -RedirectStandardInput .\generate_hprof\heap.dump.hprof

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接