【问题标题】:undefined method 'to_slice' for IO::ARGF (compile-time type is IO+)IO::ARGF 的未定义方法“to_slice”(编译时类型为 IO+)
【发布时间】:2019-05-16 08:38:57
【问题描述】:

我尝试通过 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

如何改进?

【问题讨论】:

    标签: crystal-lang


    【解决方案1】:

    Base64.decode 不采用IO 作为第一个参数,它采用响应to_slice 的东西,所以通常是StringSlice

    您必须先将整个 IO 读入内存,然后再将其传递给 Base64.decode,使用 IO#gets_to_end(鉴于它是 base64 编码数据,读入 String 应该是安全的)。

    或者,如果您想保持内存效率,您应该读取 4 的倍数的块(因为使用 base64 编码,每 3 个原始字节编码为 4 个字节),使用 IO#read(确保循环直到您的块full 并处理 EOF 情况),然后解码每个完整块并将结果写入文件,然后再为下一个块回收缓冲区。

    【讨论】:

    • 谢谢,是的 http/body.gets_to_end 有效,但我想保持内存效率
    猜你喜欢
    • 2016-01-29
    • 1970-01-01
    • 2020-12-22
    • 1970-01-01
    • 2017-09-16
    • 2014-09-14
    • 2021-03-24
    • 2020-04-14
    • 2020-04-14
    相关资源
    最近更新 更多