我试图通过IO将AJAX上传的图像data:image/gif;base64,R0lGOD...
写入文件。得到奇怪的异常
in src/controllers/product.cr:41: instantiating 'Base64:Module#decode(IO+, File)'
Base64.decode(photo_b64_io, file)
in /usr/share/crystal/src/base64.cr:173: undefined method 'to_slice' for IO::ARGF (compile-time type is IO+)
from_base64(data.to_slice) do |byte|
我的代码
photo_b64_io = env.request.body.not_nil!
photo_b64_io.gets(",") # seek to real data
File.open(File.join(upload_path, file_path, file_id), "w") do |file|
Base64.decode(photo_b64_io, file)
end
如何改进?
Base64.decode
不接受IO
作为第一个参数,它接受响应to_slice
的东西,所以通常是String
或Slice
。
您必须先将整个IO读取到内存中,然后再使用IO#gets_to_end
将其传递给Base64.decode
(考虑到它是base64编码的数据,读取到String
中应该是安全的(。
或者,如果你想保持内存效率,你应该使用IO#read
读取4的倍数的块(因为使用base64编码,每3个原始字节被编码为4个字节((确保循环直到块满并处理EOF情况(,然后解码每个完整的块并将结果写入文件,然后为下一个块回收缓冲区。