简体   繁体   English

Ruby on Rails:一定时间后,解压缩(Zlib :: Deflate)不起作用

[英]Ruby on Rails: Decompression (Zlib::Deflate) doesn't work after certain amount of time

I have a need to compress large chunk of text before saving it to the database and decompress it back once client requests it. 我需要先压缩大量文本,然后再将其保存到数据库中,并在客户端请求时将其解压缩。

The method I am using right now seems to work fine when I insert new records using the Rails console and query for the newly inserted record right away. 当我使用Rails控制台插入新记录并立即查询新插入的记录时,我现在使用的方法似乎运行良好。 ie, I can decompress the compressed description successfully. 即,我可以成功解压缩压缩的描述。

But I am not able to decompress the compressed description for any of my other records added prior to this date. 但是我无法解压缩此日期之前添加的其他任何记录的压缩description It is really confusing for me especially being a newbie to the ROR world. 对于我而言,尤其是作为ROR世界的新手,这确实让我感到困惑。

I am using MySQL as a database. 我正在使用MySQL作为数据库。

Could you please point me to the right direction? 您能指出我正确的方向吗? Please have a look at my Model below to better understand it. 请在下面查看我的模型以更好地理解它。

require "base64"

class Video < ActiveRecord::Base
  before_save :compress_description

  def desc
    unless description.blank?
      return decompress(description)
    end
  end

  private

  def compress_description
    unless description.blank?
      self.description = compress(description)
    end
  end

  def compress(text)
    Base64.encode64(Zlib::Deflate.new(nil, -Zlib::MAX_WBITS).deflate(text, Zlib::FINISH))
  end

  def decompress(text)
    Zlib::Inflate.new(-Zlib::MAX_WBITS).inflate(Base64.decode64(text))
  end
end

Ok it's actually very easy to reproduce your problem. 好吧,实际上很容易重现您的问题。 In rails console do the following 在Rails控制台中执行以下操作

Video.create(:description => "This is a test")
Video.last.description
=> "C8nILFYAokSFktTiEgA=\n" 
Video.last.desc
=> "This is a test" 
Video.last.save #This update corrupts the description
Video.last.desc
=> "C8nILFYAokSFktTiEgA=\n"

The reason the corruption happens is because you are compressing an already compressed string 发生损坏的原因是因为您正在压缩已经压缩的字符串

You should probably modify your class as follows and you should be fine 您可能应该按如下方式修改您的课程,并且应该没问题

require 'base64'
class Video < ActiveRecord::Base
  before_save :compress_description
  after_find :decompress_description
  attr_accessor :uncompressed_description

  private

  def compress_description
    unless @uncompressed_description.blank?
    self.description = compress(@uncompressed_description)
    end
  end

  def decompress_description
    unless description.blank?
      @uncompressed_description = decompress(description)
    end
  end

  def compress(text)
    Base64.encode64(Zlib::Deflate.new(nil, -Zlib::MAX_WBITS).deflate(text, Zlib::FINISH))
  end

  def decompress(text)
    Zlib::Inflate.new(-Zlib::MAX_WBITS).inflate(Base64.decode64(text))
  end
end

Now use your class as follows 现在按如下方式使用您的课程

Video.create(:uncompressed_description => "This is a test")
Video.last.description
=> "C8nILFYAokSFktTiEgA=\n" 
Video.last.uncompressed_description
=> "This is a test" 
Video.last.save
Video.last.uncompressed_description
=> "This is a test" 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM