今天发现了一个诡异的问题: 使用 OpenURI中的 open
打开远程文件的时候, 有时候返回 StringIO
, 有时候返回 Tempfile
而我的应用场景里面需要返回 Tempfile
于是翻看OpenURI的源代码发现 这样一处代码
1
2
3
4
5
6
7
8
9
10
11
12
13
| StringMax = 10240
def <<(str)
@io << str
@size += str.length
if StringIO === @io && StringMax < @size
require 'tempfile'
io = Tempfile.new('open-uri')
io.binmode
Meta.init io, @io if Meta === @io
io << @io.string
@io = io
end
end
|
这段代码的意思是, 当 io
的 size > StringMax
时, 也就是10k, 返回一个Tempfile的实例, 当小于等于10k的时候, 返回StringIO的实例
所以, 解决方法随之而来 ^_^, 如下所示, 反其道而行:
1
2
3
4
5
6
7
8
9
10
11
12
13
| require 'tempfile'
def open_as_tempfile(file_path)
io = open file_path
if StringIO === io
extname = File.extname(file_path)
tempfile = Tempfile.new(['open-uri', extname])
tempfile.binmode
tempfile.write io.string
tempfile.rewind
io = tempfile
end
io
end
|
在需要始终返回Tempfile
的地方使用open_as_tempfile
替换open
, 这样就可以保证返回的始终是 Tempfile
的实例啦