首页
/
行业洞察
/
正文
INDUSTRY INSIGHT · 深度
如何用 StringIO 把字符串当 IO 流读写?
📅 2026/9/14 11:49:46
✍️ 爱科研究院
👁 阅读 3,247
如何用 StringIO 把字符串当 IO 流读写【免费下载链接】rubyThe Ruby Programming Language项目地址: https://gitcode.com/GitHub_Trending/ru/rubyRuby 的StringIO让你把一个普通字符串当成流stream来读写行为和IO类似但数据保存在内存里。它属于 Ruby 标准库源码就在本仓库的 ext/stringio 目录中README.md 把它描述为 “PseudoIOclass from/toString”gemspec 声明的最低版本要求是 Ruby 2.7。适合的场景是代码需要一个 IO 对象做参数比如只接受IO的库函数但你的数据本身就是一段字符串不想先写临时文件。本文的所有示例都假定你已经完成这一步require stringio创建流StringIO.new 与 StringIO.open创建流有两条路径见 doc/stringio/stringio.mdStringIO.new返回一个包含给定字符串的StringIO对象StringIO.open把一个新建的StringIO对象传给块。strio StringIO.new(foobarbaz, r) strio.pos # 0 strio.string # foobarbaz选择读写模式决定初始状态与权限构造时第二个参数是访问模式可以给字符串也可以给File常量两者等价strio StringIO.new(foo, a) strio StringIO.new(foo, File::WRONLY | File::APPEND)各模式的初始状态与权限源文档中的汇总表模式含义初始是否清空字符串读写r只读否任意位置报错w只写是报错任意位置a只追加否报错仅限末尾r读/写否任意位置任意位置w读/写是任意位置任意位置a读/追加否任意位置仅限末尾选模式的依据是两点数据是否要保留w/w初始清空其余不清空以及写的位置a/a只能追加到末尾即使pos被改到别处也不受影响。权限不符时操作会抛IOError文档示例strio StringIO.new(foobarbaz, r) strio.write(foo) # Raises IOError: not opened for writing还有一个值得知道的行为在流末尾之外写入时中间用空字符补位strio StringIO.new(foo, w) strio.pos 9 strio.write(baz) strio.string # \u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000baz # Null-padded文档示例数据模式与编码t 与 b 后缀任一读写模式后面还可以追加数据模式后缀t文本初始编码为Encoding::UTF_8b二进制初始编码为Encoding::ASCII_8BIT。两者都不给时流默认按文本处理。文档示例strio StringIO.new(foo, rt) strio.external_encoding # #Encoding:UTF-8 strio StringIO.new(data, rb) strio.external_encoding # #Encoding:BINARY (ASCII-8BIT)注意指定了数据模式后缀时读写模式不能省略否则会报错StringIO.new(data, b) # Raises ArgumentError: invalid access mode b后续可以用#set_encoding改编码例如strio.set_encoding(US-ASCII)#internal_encoding固定返回nil因为流没有内部编码。定位pos、seek、rewind 与 eof?流有一个按字节计的位置position新建流初始为 0。文档中列出的定位方法#pos返回当前位置#pos设置位置#rewind位置归零#seek设置位置#eof?判断位置是否已到流末尾。文档示例可直接照抄验证strio StringIO.new(foobar) strio.pos # 0 strio.pos 3 strio.pos # 3 strio.eof? # false strio.rewind strio.pos # 0 strio.seek(0, IO::SEEK_END) strio.pos # 6 strio.eof? # true位置还决定了读写从哪里开始除#pread外读方法从当前位置开始并推进位置#putc、#write、Kernel#puts从当前位置开始写并推进位置#ungetc/#ungetbyte则在当前位置之前写入并把位置回退使写入的数据成为接下来要读到的内容。#truncate截断字符串但不改变位置。从流里读read、gets、each_line 与 pread读方法清单来自 doc/stringio/stringio.md 的 Basic Reading 一节#getbyte读下一个字节#getc读下一个字符#gets读下一行或行的一部分#read读剩余数据或其中一部分#readlines把剩余数据读成行数组返回#each_byte/#each_char/#each_codepoint/#each_line迭代读取#pread按偏移量读不改动流自身。#read的要点见 read.rdoc不给参数读全部剩余数据给非负maxlen时最多读maxlen个字节读不到字节返回nilstrio StringIO.new(Hello) strio.read # Hello strio.pos # 5 strio.read # strio.rewind strio.read(3) # Hel strio.read(3) # lo strio.read(3) # nil#gets支持三种参数形态无参数用默认记录分隔符$/初始值\n字符串参数sep用作自定义分隔符整数参数limit限制每行最大字符数。另有chomp: true关键字参数可去掉行尾换行见 gets.rdocstrio StringIO.new(TEXT) strio.gets # First line\n strio.gets(chomp: true) # Second line#each_line同理支持sep、limit与chomp:且支持 IO 的两个特殊分隔符按段空行分隔读、nil一次读完见 each_line.mdstrio StringIO.new(TEXT) strio.each_line() {|line| p line } # 按段读取 strio.each_line(nil) {|line| p line } # Slurp一次读完多线程场景下用#pread(maxlen, offset)它从给定偏移读取不修改流自身因此多个线程可以安全地读同一个流见 pread.rdoc。注意它返回的字符串编码固定为Encoding::ASCII_8BIT且偏移越界时抛EOFError: end of file reached。往流里写write、putc、ungetc 与 truncate写方法清单#write把对象当作字符串写入当前位置#putc写入一个字符对多字节字符是替换对应字节细节见 putc.rdocKernel#puts写入并各自跟随换行#ungetc/#ungetbyte在当前位置之前插入数据并回退位置#truncate把流的字符串截断到给定大小位置不变。文档示例一条完整的写入路径及其位置变化strio StringIO.new(foo) strio.pos # 0 strio.putc(b) strio.string # boo strio.pos # 1 strio.write(r) strio.string # bro strio.pos # 2 strio.puts(ew) strio.string # brew\n strio.pos # 5验证结果用 string、size、eof? 检查StringIO与真实IO的关键区别在于你可以直接看到背后的字符串这就是验证手段strio.string # 当前流的完整内容 strio.size # 当前字符串的字节数 strio.pos # 当前位置 strio.eof? # 是否已到末尾文档给出的size示例见 size.rdocStringIO.new(hello).size # 5 StringIO.new(こんにちは).size # 15 # 五个 3 字节字符一套可照做的验证顺序全部来自源文档示例创建流后检查strio.pos应为 0和strio.string按模式决定是原字符串还是已清空读写后检查strio.string与strio.pos是否符合上述规则读完整段数据后strio.eof?应为true。StringIO 与 IO 的两个差异ext/stringio/README.md 明确列出了与IO的差别涉及IO兼容代码时要留意fileno会抛NotImplementedError——字符串没有文件描述符任何通过fileno取文件句柄的用法都不可行编码转换encoding conversion未实现会被静默忽略——所以不要指望set_encoding同时完成转码它只改变流的编码标记。这两条是文档给出的边界除这两点外StringIO提供与IO相近的行/字符/字节读写接口见 doc/stringio/stringio.md 的 Line IO、Character IO、Byte IO 各节。【免费下载链接】rubyThe Ruby Programming Language项目地址: https://gitcode.com/GitHub_Trending/ru/ruby创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
📌 标签:
工业官网
设计趋势
AI 建站
SEO
获取完整报告 →
RELATED ARTICLES
推荐阅读
2026/9/14 11:49:46
Spree 搜索提供程序架构:可插拔的搜索、过滤与 Facet 聚合接口(Search Provider)
2026/9/14 11:49:46
Apache DolphinScheduler 接入 DolphinDB 数据源:从界面配置到插件激活的完整实战指南
2026/9/14 11:49:46
MATLAB示波器谐波分析:从FFT到电能质量指标的工程实践
2026/9/14 12:29:50
MongoDB 分片过滤场景下 DISTINCT_SCAN 计划缓存行为深度解析:基于 shard_filtering_plan_cache Golden Test
2026/9/14 12:29:50
Data-Science-For-Beginners 仓库工程指南:环境搭建、构建测试与多语言翻译体系(基于 AGENTS.md)
2026/9/14 12:29:50
酒店管理系统工程文件实战:从表设计到可交付部署的完整指南
2026/9/14 12:29:50
基于CNN的柑橘病变智能识别系统设计与实现
2026/9/14 12:29:50
嵌入式FFT示波表:现场级频谱分析的工程落地实践
2026/9/14 12:24:49
VictoriaMetrics 流式聚合配置指南:streamAggr 配置格式、聚合函数与热加载实战
2026/9/14 0:03:40
KCF目标跟踪算法与OTB工程实现:毕业设计实战解析
2026/9/14 0:03:40
Megatron-LM 推理实战指南:基于 Megatron Core 高层 API 的离线推理与 OpenAI 兼容服务
2026/9/14 0:03:40
语音情感识别实战:Keras实现LSTM、CNN、SVM与MLP多模型对比
2026/9/14 7:37:16
拯救者Y7000黑屏故障排查与维修实战指南
2026/9/14 2:50:57
AI SDK Harness 依赖更新指南:掌握 harness 包 SDK 依赖的升级、桥接同步与一致性校验
2026/9/14 11:25:37
Refine v5 Ant Design NumberField 组件实战:基于 Intl 的本地化数字格式化