FLYING

〈全日本・紀文豆乳飲料シリーズ「麦芽コーヒー」の500ミリリットルパックを扱う小売店が少ないことに遺憾の意を表明する会〉活動記録

里芋的スクリプト「山芋」

山芋おいしいです

ファイル圧縮ツール「里芋」の発想をまんまパクったスクリプトです。Rubyで書いてあるので色んな処理系で動くかもしれません。細かい部分はid:teturouetのやり方をパクりました。Base64をベースにしているので、id:teturouetスクリプトよりもたぶん効率がいいです。あまり大きいファイルを解凍しようとするととんでもないことになると思われます。

使い方

# 圧縮
ruby yamaimo.rb hogehoge.zip
# 解凍
ruby yamaimo.rb hogehoge.zip.0/

ソース

#!/usr/local/bin/ruby -Ks

# must be a multiple of 3
BLOCK_SIZE = 150

def pack(buf)
  [buf].pack("m").gsub(/\//, "-").gsub(/\n/, "")
end

def unpack(buf)
  buf.gsub(/-/, "/").unpack("m").first
end

def zip(target)
  output_dir = "#{target}.0"
  Dir.mkdir(output_dir)
  f = open(target, "rb")
  count = 0
  while buf = f.read(BLOCK_SIZE) do
    name = sprintf("%d@%s", count, pack(buf))
    open("#{output_dir}/#{name}", "wb").close
    print("#{count}\r")
    count += 1
  end
  f.close
end

def unzip(target)
  output_name = target[0..-4]
  f = open(output_name, "wb")
  array = Dir.entries(target).sort {|a, b|
    a.to_i <=> b.to_i
  }
  count = 0
  array.each {|file|
    f.write unpack($1) if file =~ /^[\d]+@(.*)$/
    print("#{count}\r")
    count += 1
  }
  f.close
end

# usage
if ARGV.size == 0 then
  puts("yamaimo.rb [path]")
  puts("[path] is file -> zip")
  puts("[path] is direcotry -> unzip")
  exit
end

# main
target = ARGV[0]
if File.directory?(target) then
  unzip(target)
elsif File.file?(target) then
  zip(target)
else
  puts("no such a file or directory")
end