我一直在使用基于字符数来分割文件内容,因为我的一个应用程序不支持任意数量的字符。所以我必须根据字符数分割内容,并根据总字符数多次更新。
c_max = 50000
f = File.new(filename)
u_count = (c_count / c_max.to_f).ceil
i = 1
while i <= u_count do
u_characters = f.sysread(c_max)
# do stuffs
i+=1
end
但是当我使用字符串而不是文件名时它不起作用。
content=File.read(filename)
#doing some stuffs on the contents
irb(main):006:0> content.sysread(10)
NoMethodError: undefined method `sysread' for #<String:0x7f5f2eedd368>
from (irb):6
from :0
irb(main):007:0>
答案 0 :(得分:2)
如果您尝试限制字符数IO#each_line
可以帮助您解决此问题,例如
c_max = 100
File.open(filename) do |file|
file.each_line(c_max) do |characters|
# characters is now a string that is 100 characters long
# do something with characters
end
end
或者要处理String
,您可以将其设为StringIO
,而#each_line
也可以使用(请注意String#each_line
无效,因为它只接受分隔符({ {1}})而不是字符数限制(String
)这就是我们需要Fixnum
)的原因
StringIO
让我们处理两个选项更新:(基于与@CarySwoveland的评论讨论 - 感谢您进一步推动我)
s = "THIS IS A STRING"
StringIO.open(s) do |strio|
strio.each_line(2) do |characters|
# characters is now a string that is 2 characters long
# do something with characters
end
end
由于这会使用枚举器功能,因此无需先将整个def do_stuff(line)
# common functionality goes here
puts line
end
# return is a StringIO or File
# leaks file descriptor handle as you wish
def my_method(s,sep_or_char_limit=100)
target = s.to_s # leverage a little duck typing
target_class = File.file?(target) ? File : StringIO
target_class.open(target) do |io|
io.each_line(sep_or_char_limit, &method(:do_stuff))
end
end
读入内存,或者整个File
不需要拆分为临时{{1 }}。
此处还有其他隐藏功能。您要求按字符限制,但如果您愿意,这也允许使用分隔符。例如
String
答案 1 :(得分:1)
问题是String对象没有sysread
方法。要获取String对象的前n个字符,可以使用String slice(range)
:
content[0...10]
或slice(start, length)
:
content[0, 10]