FLYING

/* TODO: 気の利いた説明を書く */

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

山芋おいしいです

ファイル圧縮ツール「里芋」の発想をまんまパクったスクリプトです。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