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

发布于 2024-12-10 10:23:40 字数 802 浏览 0 评论 0原文

我需要在将大块文本保存到数据库之前对其进行压缩,并在客户端请求时将其解压回来。

当我使用 Rails 控制台插入新记录并立即查询新插入的记录时,我现在使用的方法似乎工作正常。即,我可以成功解压压缩的描述。

但我无法解压缩在此日期之前添加的任何其他记录的压缩描述。这对我来说真的很困惑,尤其是作为 ROR 世界的初学者。

我使用 MySQL 作为数据库。

请参阅下面的模型以更好地理解它。

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

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. i.e., 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. It is really confusing for me especially being a beginnner to the ROR world.

I am using MySQL as a database.

See 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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

时光与爱终年不遇 2024-12-17 10:23:40

好的,实际上很容易重现您的问题。在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"

操作发生损坏的原因是因为您正在压缩已经压缩的字符串

您可能应该按如下方式修改您的类并且应该没问题

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

现在按如下方式使用您的类

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" 

Ok it's actually very easy to reproduce your problem. In rails console do the following

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" 
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文