我有一个ruby脚本,在某个时刻,它有一个内存文件,可能会也可能不会被文件系统中的条目支持。如果文件系统条目不存在,那么天真的解决方案是创建一个临时文件,但这会导致命令行命令将文件重新读入内存。
理想情况下,我希望避免将文件多次读入内存,因为它可能会非常大。
现在,命令行命令确实接受管道输入,所以我认为这可能是一个很好的解决方案,但我找不到任何方法来实现将Ruby File对象的内容管道化为命令行上发生的事情
如果我从错误的方向来到这里,我也会接受其他建议。正在从远程HTTP流中读取未由文件系统条目支持的文件。
答案 0 :(得分:1)
一种方法是将IO
内容读入字符串,然后使用Kernel#open
(|
),IO::popen
或{{3创建子进程并将内容写入子进程stdin:
f = the_file_or_io_object
data = f.read
IO::popen('the_command', 'r+') do |io|
io.write data
io.close_write
puts io.read
end
虽然这可以避免将文件写入磁盘(除非它已经与例如tempfile一起),但它涉及将文件内容读入内存然后将它们传递给子进程,因此它们在内存中两次。如果您想避免使用open3
(如果您的系统有)和fork
:
# f as before, no need to read it in this time
pid = fork do
$stdin.reopen f
# Now stdin is the file, so when the command is run it will see
# it on its stdin
exec 'the_command'
end
Process.wait pid
如果你在Windows上,你可能没有fork
,所以你可以尝试reopen
,重定向stdin
:
pid = spawn 'the_command', :in => f
Process.wait pid