Ruby中如何在文件流的源与接收端之间添加过滤转换操作
Ruby流中间转换实现方案
Ruby标准库原生支持简便的流式处理能力,不需要自定义IO包装类,常用实现方案如下:
方案1:枚举器链式转换(绝大多数场景首选)
Zlib::GzipReader本身实现了Enumerable接口,可以直接通过惰性枚举实现流式转换,全程不会一次性加载全量文件到内存:
require 'zlib' require 'csv' Zlib::GzipReader.open('/tmp/foo.psv.gz') do |gz_stream| # 逐行转换后生成惰性枚举器,直接传给CSV解析 transformed_stream = gz_stream.each_line.lazy.map { |line| line&.tr('|', ',') } CSV.new(transformed_stream).each do |row| puts row.inspect end end
该方案代码极简,性能和自定义IO包装类一致,完全满足示例中的需求。
方案2:IO管道转换(需要标准IO对象时使用)
如果下游依赖只接受标准IO类型的参数,可以用Ruby自带的IO.pipe实现转换层,不需要自己维护行缓冲区:
require 'zlib' require 'csv' gz_stream = Zlib::GzipReader.open('/tmp/foo.psv.gz') read_io, write_io = IO.pipe # 启动独立线程做转换,不会阻塞主解析流程 Thread.new do gz_stream.each_line do |raw_line| write_io.write raw_line&.tr('|', ',') end write_io.close ensure gz_stream.close end CSV.new(read_io).each do |row| puts row.inspect end
内容的提问来源于stack exchange,提问作者akim
相关产品推荐
相关产品推荐

