実験データをZIPで固めて、メールで送ってもらったのだが、
受信に失敗したので再送してもらおうと思ったが、今度は送信でこけた。
元ファイルは今手元にないのだが、過去に送ったメールはメールソフトに残ってる。
というわけでこれを探して、メールのソースをアップロード。
これでデータは家で取ることが出来た。けどBase64でエンコードされてる。さあどうする。
こういうときにPerlを使うんですね。
まぁBase64のデコードはMIME::Base64のdecode_base64関数でやればよいと。
なんてことないですね。
use strict;
use warnings;
use MIME::Base64;
open my $if,'<','in.txt';
my $b='';
$b.=$_ while(<$if>);
close $if;
open my $of,'>','out.zip';
print $of decode_base64($b);
close $of;
非常にわかりやすいプログラムですね。
たまには決まり文句も書きましょうか。
in.txtを開いて、1行ずつ読んで、これをどんどんくっつけて$sを作る。
まぁ多分これでOKだと思います。
ReadToEndメソッドみたいなのは、確かなかったはずだし。
それで$sを全部decode_base64でデコードする。
ここで1行ずつ読み込んではデコードして書き込んでも多分OK。
ただBase64は4文字セットで処理しないといけないのだが、
改行の位置がおかしいと1行が4文字単位になってないことがある。
なので一応全部読み込んでから処理するようにしてる。
しかし!ファイルが破損していると出る。
実は、これはLinuxでコマンドラインで使う1行プログラムを参考に作った。
$ perl -MMIME::Base64 -e "print decode_base64($_) while(<>)" < in.txt >out.zip
-MXXXはuse XXX;に相当するかな。XXXというパッケージを読み込むと。
リダイレクトで標準入力から入力ファイルを入れて、
標準出力に出したやつをリダイレクトで出力ファイルに出す。
結構Linuxとかでは使います。便利です。
しかしWindowsでこの方法が通用しないのはもう何度も体験している。
というのも、Windowsでは入出力全般で、入力時CR+LFとなっているものはLFのみに変換され、
出力時LFはCR+LFに変換される。というなんかよくわからない機能が付いていると。
これが結構困るんですね。それでさっきの1行プログラムはその辺考えてないと。
そういう事実にはすぐ気付いたのだが、自分でプログラム書いたらそれを忘れてたと。
binmode $of;
これで$ofをバイナリモードにすると。
これを$ofを開いた後に入れればOKです。めでたしめでたしと。
ちなみにさっきの1行プログラム、いろいろ試してたがこうすればWindowsでも動く。
perl -MMIME::Base64 -e "binmode STDOUT; print decode_base64($_) while(<>)" < in.txt >out.zip
まぁSTDOUTをバイナリモードにしておけば問題ないですね。
Linuxではこれを気にせずに、バイナリを流せるんですけどね。
$ tar cvf - foo/ | bzip2 -c | uuencode foo.tar.bz2 | mail hidemaro
まぁこんな具合にバイナリだろうがテキストだろうが、パイプを行き交うと。
最近では使いませんけど、昔はtarで標準出力に出したり標準入力から読んだりと、
そういうときはファイル名のところに-を当てはめればよろしいと。
これをすればfoo/をtar.bz2で固めてメールで送ってくれる。
Windowsではこんなことしませんよね。
僕はパイプ名人でもないけど、コマンドを通して処理するとかいうのは、
結構便利だからWindowsでも活用したいなと思うけど結構難しい。
以前それがためにCygwinを入れてたけど、再インストールの時に入れなかったからね。
最近は結構Perlでできることが多いことに気付いて、
自作したperlshで、試行錯誤しながら、CPANも活用しつつやってます。
そっちの方が柔軟にできるのでね。
今更どうにもならないけど、もっとパイプが使いやすい仕様ならなと思わないこともない。