如何使用Perl将STDIN的二进制内容保存到指定文件中
Perl实现等待STDIN数据后二进制保存的方案
核心需求实现(满足所有要求)
直接使用以下单条命令即可,无需额外安装依赖,全平台兼容:
# 通用用法:输入流 | perl -e '$f=shift; sysread(STDIN, $buf, 1) || exit; open(O, ">:raw", $f) || die $!; print O $buf; while(sysread(STDIN, $buf, 4096)) { print O $buf }' 目标文件名 # 示例 echo hello | perl -e '$f=shift; sysread(STDIN, $buf, 1) || exit; open(O, ">:raw", $f) || die $!; print O $buf; while(sysread(STDIN, $buf, 4096)) { print O $buf }' my_filename.txt
逻辑说明:
- 先用
sysread(STDIN, $buf, 1)阻塞等待STDIN至少有1字节数据到达,没读到数据(输入流为空/关闭)时直接退出,不会创建或修改目标文件,完全解决shell重定向先开文件的特性问题 - 确认有数据后才用
>:raw二进制模式打开目标文件,不会做任何编码转换,天然兼容UTF-8文本、二进制文件等所有格式 - 先写入已读到的1字节,再每次读取4KB块循环写入,内存占用固定,支持处理任意大小的输入流
- 支持通过第一个参数直接指定目标文件名,无需硬编码在脚本中
你之前的尝试错误点:
open STDIN, ">", 文件名是将STDIN重定向为写入到文件,直接覆盖了输入流句柄,自然读不到输入内容;而<STDIN>在标量上下文下默认只读一行,遇到换行就终止,无法读取全部输入。
额外需求实现
读取指定文件内容写入STDOUT
同样为二进制模式,跨平台兼容:
perl -e '$f=shift; open(I, "<:raw", $f) || die $!; while(sysread(I, $buf, 4096)) { print $buf }' 源文件名
读写文件串联示例
如果需要读本地文件写入另一个本地文件,同样满足「先确认源文件可读再创建目标文件」的逻辑:
perl -e '$src=shift; open(I, "<:raw", $src) || die $!; sysread(I, $buf,1) || exit; $dst=shift; open(O, ">:raw", $dst) || die $!; print O $buf; while(sysread(I,$buf,4096)){print O $buf}' 源文件名 目标文件名
内容的提问来源于stack exchange,提问作者Zack Morris
相关产品推荐
相关产品推荐

