无法使用 Rails 中的 redis gem 在 Redis 中正确保存图像



我正在尝试将图像保存到Redis,稍后将在Resque任务中获取并上传到我们的图像服务器。

ImageHandle类将为我们获取图像。目前,我只关心在Redis中获取图像。

class ImageHandle < ActiveRecord::Base
  attr_accessible :uploaded, :image
  after_save :save_image
  def image_data
    $redis.get(redis_key)
  end
  def image=(value)
    @image = value
  end
  private
  def redis_key
    @redis_key ||= "image_handle:#{id}:image"
  end
  def save_image
    $redis.set(redis_key, @image.read)
  end
end

其中$redis是在初始化器中设置的:

$redis = Redis.new

这是我的测试文件:

require 'test_helper'
class ImageHandleTest < ActiveSupport::TestCase
  include ActionDispatch::TestProcess
  setup do
    clear_redis
  end
  test 'saves an image' do    
    image = fixture_file_upload('screaming-eagle.jpg', 'image/jpg')
    # You can only read from a file fixture once
    same_image = fixture_file_upload('screaming-eagle.jpg', 'image/jpg')
    image_handle = ImageHandle.create(image: image)
    expected = same_image.read
    actual   = image_handle.image_data
    puts "length of expected: #{expected.length}"
    puts "length of actual:   #{actual.length}"
    assert_equal expected, actual
  end
end

结果是:

length of expected: 81500
length of actual:   78524
F 
Finished tests in 0.270385s, 3.6984 tests/s, 3.6984 assertions/s.
  1) Failure:
test_saves_an_image:23

我不知道发生了什么事。

当我尝试设置("b"*81500)然后获取它时,我将它恢复到预期的81500长度。

谢谢你能给我的任何帮助。

redis-rb将字符串转换为默认的外部编码,该编码由Encoding::default_external定义,通常为UTF-8。看见https://github.com/redis/redis-rb/commit/61fa1f884a643cd7dea8e0e56498860594058a39

您可以在存储二进制数据之前将其编码为Base64,并在检索后从Base64解码:

class ImageHandle < ActiveRecord::Base
  attr_accessible :uploaded, :image
  after_save :save_image
  def image_data
    Base64.decode $redis.get(redis_key)
  end
  def image=(value)
    @image = value
  end
  private
  def redis_key
    @redis_key ||= "image_handle:#{id}:image"
  end
  def save_image
    $redis.set redis_key, Base64.encode(@image.read)
  end
end

您可以在不丢失数据的情况下将字符串转换为ASCII-8BIT。更新此方法:

def image_data
  $redis.get(redis_key).force_encoding(Encoding::ASCII_8BIT)
end

它比Base64更快、更简单。

最新更新