ファイルがあるのに「No such file or directory」
Windows上でRubyを使っていると、ファイルパスに特殊文字を含んだファイルを扱う事がある。e.g.,
».htm ®.htm ™.htmこれらのファイルをRubyスクリプトの引数で渡してもファイル名が化けてしまったりしてうまく扱えない。
こんなRubyスクリプトに渡してみる。
#!ruby # -*- coding: utf-8 -*- puts File.basename( ARGV[0] ) puts File.exist?( ARGV[0] ) puts File.exist?( ARGV[0].dup.force_encoding( 'utf-8' ) ) puts ARGF.path環境はWindows 7、Ruby 1.9.3、
Encoding.locale_charmap
がCP932
。
このスクリプトに先のファイル名を与えると以下のような結果になる。
».htm
≫.htm false false file_check.rb:7:in `path': No such file or directory - ≫.htm (Errno::ENOENT) from file_check.rb:7:in `<main>'
®.htm
R.htm false false file_check.rb:7:in `path': No such file or directory - R.htm (Errno::ENOENT) from file_check.rb:7:in `<main>'
™.htm
R.htm false false file_check.rb:7:in `path': No such file or directory - R.htm (Errno::ENOENT) from file_check.rb:7:in `<main>'UTF-8のバイナリで表すと、以下のように文字が変化してしまっている。
».htm -> ».htm (0xC2 0xBB -> 0xE2 0x89 0xAB) ®.htm -> R.htm (0xC2 0xAE -> 0x52) ™.htm -> R.htm (0xC2 0xE2 0x84 0xA2 -> 0x52)どーしたらいいんでしょうか。
できる対処法
とりあえず、Rubyをキックするバッチを作って、その中でテンポラリディレクトリにファイルを複製、リネームして、そのファイルをRubyスクリプトに与えることで対処。こんなかんじ。
SET FDATE=%date:~2% SET FTIME=%time:.=-% SET FTIME=%FTIME: =% SET TEMP_F="%TEMP%\%FDATE:/=-%_%FTIME::=-%%~x1" COPY %1 %TEMP_F% C:\Ruby193\bin\ruby file_check.rb %TEMP_F% DEL %TEMP_F%Rubyの中で、オリジナルのパス名が必要なら、こんなカンジ。
SET FDATE=%date:~2% SET FTIME=%time:.=-% SET FTIME=%FTIME: =% SET TEMP_F="%TEMP%\%FDATE:/=-%_%FTIME::=-%%~x1" COPY %1 %TEMP_F% C:\Ruby193\bin\ruby file_check.rb %TEMP_F% %1 DEL %TEMP_F%とりあえずファイル読めるようになる。
もっと効率良い方法あると思うので、教えてください。