xxxUploader 类中的函数实现
def filename
if original_filename
@name ||= Digest::MD5.hexdigest(File.dirname(current_path))
"#{@name}.#{file.extension}"
end
end
XXXX model类中的定义
mount_uploader :xxx_file, xxxUploader
xxxx controller类中的定义
Dir.foreach("/home/xxxx/test/") { |file|
ext_name = File.extname(file)
if ext_name == ".rar" or ext_name == ".zip" or ext_name == ".7z" then
xxx_img = XXXX.new
xxx_img.xxx_file = File.open("/home/xxx/test/" + file )
xxx_img.save!
end
}
最后发现model中的xxx_file有重复的名字?
你是说 http://huacnlee.com/blog/carrierwave-upload-store-file-name-config/ 这篇文章
current_path
是 Carrierwave 创建的时候根据时间来的一个地址,理论上是不会重复的呀,我来查查
Carrierwave 的 current_path
的产生方式这这么来的:
Time.now.utc.to_i.to_s + '-' + Process.pid.to_s + '-' + ("%04d" % rand(9999))
我刚刚才 IRB 里面测试了一下
irb(main):017:0> a = []
=> []
irb(main):018:0> 10000.times { a << Time.now.strftime('%Y%m%d-%H%M') + '-' + Process.pid.to_s + '-' + ("%04d" % rand(9999)) }
=> 10000
irb(main):019:0> puts a.count
10000
=> nil
irb(main):020:0> puts a.uniq.count
6228
=> nil
所以,在一瞬间爆发上传请求的时候,重复的概率是有的,确实目前的方法是有问题的,当初我忽略了这个问题,抱歉啊!
如果不用 File.dirname(current_path)
而是直接用 current_path
重复的概率应该没了
@huacnlee 大大,打算提交到https://github.com/ruby-china/ruby-chinamerge上吗?我直接 ruby-china 就好啦?
@huacnlee 大大 后来我仔细看了下代码发现日志不符合代码预期
def self.generate_cache_id
Time.now.utc.to_i.to_s + '-' + Process.pid.to_s + '-' + ("%04d" % rand(9999))
end
def filename
if original_filename
@name ||= Digest::MD5.hexdigest(current_path)
Rails.logger.info(">>>>>>>>>>>>>>>>>> #{current_path} #{File.dirname(current_path)} #{original_filename} #{cache_id} #{CarrierWave.generate_cache_id}")
"#{@name}.#{file.extension}"
end
end
打印出来的日志是
xxxxxxx/20131105-1631-9879-1501/__1.zip xxxxxxx/20131105-1631-9879-1501 __1.zip 20131105-1631-9879-1501 20131105-1631-9879-2339