FenrirFS Portable を本当に持ち運ぶ為に

  • なんだか成功した臭いのでまずはメモしておこう。以下では FenrirFS がどういうものであるか分かっている人向けに書く。
  • FenrirFS Portable は、USB メモリに入れて使うものとして開発されたのだが、本当に持ち運んで使おうとすると、不具合が出る。それは、エイリアスモードで使用していると、USB 差し込み口が変わることでドライブレターが変わり、それ故にエイリアスのリンクが参照している場所が無くなってしまってファイルが開けなくなるという不具合だ。今回は、それを何とかしてみようと思った。
    • 以下では、FenrirFS Portable は同じ USB メモリに入っている資料ファイルをエイリアスで参照しているものとする。
  • 各ファイルに対するエイリアスファイルは、「[ドライブレター]:/PortableFenrirFS/FenrirFS Storage/[なんとか].profile/files/」に詰め込まれているのが分かるだろう。拡張子は 「.alias」 である。これを適当なエディターで開いてみると、次のように書いてある。
Target=[ドライブレター]:\[以下、同 USB メモリ内のファイルの場所]
DisplayName=[なんとかかんとか]
WorkDir=
Arguments=
ShowCmd=0
  • このエイリアス中のドライブレターは、初めてこのエイリアスが作られた時にその USB メモリーに割り当てられていたドライブレターであったはずだ。このドライブレターが不変であることが、問題の種である。だから、目下の不具合を解決する為にはこのドライブレターを変更してやればいい。
  • これが技術的に難しいのは、エイリアスの数が膨大だからである。とても手作業で出来るものでは無く、また USB を突き刺す場所が変わるたびにそれを行うというのは決して現実的ではない。
  • そこで、私は今回 Ruby (1.9.3p385) のプログラムによってこれを自動化することを考えた。適切なドライブレターが分かっているという条件下で、ドライブレターを自動で書き換えるプログラムを組もうと思ったのである。
  • 現時点での私の解決法は、「files」 フォルダー中のエイリアスファイル全てを一斉に書き換えるものではなく、とりあえず一つのファイル中のドライブレターを書き換えるものである。
variable = File.read('[目下のドライブレター]:\[以下、同 USB メモリ内のファイルの場所]', {:mode => 'r:UTF-16LE:[Ruby プログラムのエンコーディング]'})
puts variable[8] = '[適切なドライブレター]'

File.open '[目下のドライブレター]:\[以下、同 USB メモリ内のファイルの場所]', 'w:UTF-16LE:[Ruby プログラムのエンコーディング]' do |f|
  f.write variable
end
    • なお、「目下のドライブレター」と「適切なドライブレター」は一致する。なぜなら、エイリアスファイルと、それが参照すべきファイルは同じ USB メモリーに入れられているからである。
  • ここで大事なのは、「UTF-16LE」 と「[Ruby プログラムのエンコーディング]」の箇所である。この二つは、順に、読み込まれる・書き出される .alias ファイルのエンコーディングと、Ruby プログラムのエンコーディングを指定している。特に、本来 FenrirFS の .alias ファイルのエンコーディングが 「UTF-16LE-BOM」 だ、ということが重要である。実は、Ruby はこのエンコーディングをサポートしていない。仕方ないので UTF-16LE でエンコードしてみたらうまくいったのでよかったね、ということであるに過ぎない。というかなんで UTF-16LE-BOM なんていうレアなエンコーディングにしてあるのか。おれは利点を知らない。
    • ちなみに、このプログラムで UTF-16LE-BOM の .alias を読み込んで書き出しても、その結果のファイルは UTF-16LE-BOM のままである。その理由は、多分ファイル冒頭の BOM のバイト列に手を付けないからだろう。と思う。
  • ともあれ、このエンコーディングだと、ドライブレターが variable[8] の位置に来るので、それを適切なドライブレターで置き換えてやればよい。
  • まあとりあえずここまで出来たからよしとしよう。あとは files フォルダ全体にこれを適用してやればよい。よいよい。
  • (6,05) というわけで、作ってみましたよ。
#encoding: utf-8

# ユーザーの環境に従って適切であるドライブレターを書き込め。
suitable_driveletter = 'E' # 左の E の部分を書き直してください。


# 変数定義。
filecount = 0
skipped = 0
done = 0

# 本体。
filenames = Dir["#{suitable_driveletter}:/PortableFenrirFS/FenrirFS Storage/個人用.profile/files/*.alias"].sort # 「個人用.profile」 の部分は適当に変えなさい。

filenames.each do |f|
  filecount += 1
  content = File.read(f, {:mode => 'r:UTF-16LE:UTF-8'})
  if content[8] != "#{suitable_driveletter}"
    content[8] = "#{suitable_driveletter}"
    File.open f, 'w:UTF-16LE:UTF-8' do |g|
      g.write content
      puts 'No.' + filecount.to_s + " \"#{f}\" done."
      done += 1
    end
  else
    puts 'No.' + filecount.to_s + " \"#{f}\" skipped."
    skipped += 1
  end
end

# 処理した数を、そのタイプによって分けて表示します。
puts done.to_s + ' done.'
puts skipped.to_s + ' skipped.'
puts filecount.to_s + ' processed.'
    • ドライブレターを書き換える必要が無いファイルはスキップします。
  • ま、僕がまだよく分かってなくて記述が冗長になっている感もするが (f の中の g とか)、とりあえずこれで幸せな結果が得られたからいいや。また習熟度が上がったら考えてみよう。
    • ちなみに、対象としているフォルダーに、ruby の数え方で 8 文字未満の .alias ファイルがあると、それを読み込んだ時点でエラーになるので、そういうファイルは削除するとかしてフォルダーから取り除いてください。ま、普通はそんな .alias ファイルが紛れ込むことは無いと思うけど、僕は手違いで .alias ファイルを変な仕方で上書きしてしまったのでそういうことが起こりました。
  • それにしても FenrirFS Portable の特殊事情に困っていて、Ruby が使える人だけが嬉しい記事ですが、大丈夫ですか。ブログはそれでいいのよ。

2014,07,30木の追記

  • この記事がそれなりに参照されているようで、書いた本人としては嬉しい。しかし、この度この記事に従ってもう一度書き換えをやってみようとしたが、上手くいかない。
  • 結論から言うと、幾ら各エイリアスのドライブレターを統一的に書き換えたとしても、Fenrir FS のデータベースが変わらない限りは、実質的に意味がない。そこで、このデータベースにも手を加える方法を探した。結論から。F:\PortableFenrirFS\FenrirFS Storage\個人用.profile\db などに置かれているデータベースファイル、「FenrirFS.db」 を適当なテキストエディターで開いて、ドライブレターを全て置換する。具体的には、かつてエイリアスの参照していた場所が全て、ドライブレター込みで 「E:\Data」 という文字列から始まり、これからのエイリアスが参照する場所が全て、ドライブレター込みで 「F:\Data」 から始まっているのなら、この二つのフレーズで置換する。勿論、:\Data とかと言っているのは、ドライブレターを、そしてドライブレターだけを確実に拾い上げる為のテクニックに過ぎない。データベース中には、色んな文字が出てくるから、F や G だけでは紛れてしまうだろう、ということだ。こうしてデータベースファイルの強制的な書き換えが済んだら、Fenrir FS を起動してみる。私の場合はこれで上手くいったが、勿論今後の成功を保証する物では何ら無い。
  • なお、F:\PortableFenrirFS\FenrirFS Storage\個人用.profile\db_bkp には、データベースファイルのバックアップが生成されるので、実際にデータベースファイルを弄る前に、ここなどを利用してバックアップを取得しておくのがいいだろう。
  • この記事も、いつかちゃんと書き直したい。しかし、いつ書き直せるのだろう。