まだ重たいCMSをお使いですか?
毎秒1000リクエスト を捌く超高速CMS「adiary

2015/01/08(木)pure perl で JPEG の Exif を表示や削除したい

機能

  • 対応はJPEGファイルのみ。
  • 外部モジュール不要。
  • 再圧縮せずにExif情報を削除することができます。
  • Exif判別やExif表示はやや手抜きですが、よほど特殊なJPEGでない限り問題にならないと思います。
  • ライセンスはWTFPLですが、一言「使ったよ」ってコメントくれると嬉しいです。

バグがあったら具体的なJPEGデータと共にコメントください。

スクリプト

続きを読む

2014/08/28(木)Windows上での flock の不具合?

これだからWindowsは……。

ロック状態を変更できない

use Fcntl;

my $fh;
sysopen($fh, "test.txt", O_CREAT | O_RDWR) or die;
flock($fh, Fcntl::LOCK_SH());
flock($fh, Fcntl::LOCK_EX());
close($fh);

Linuxなどでは、共有ロックが排他ロックに切り替わるのですが、Windows上では切り替えることができず*1、そのままブロッキングされてしまいます。

*1 : 自分自身で獲得した共有ロックが、排他ロックを獲得する際の障害になっている

共有ロック状態でtruncateすると、ファイルサイズが固定される

use Fcntl;

my $fh;
sysopen($fh, "test.txt", O_CREAT | O_RDWR) or die;
flock($fh, Fcntl::LOCK_SH());

truncate($fh, 0);		# ファイルサイズを 0 に
seek($fh, 0, 0);		# ファイルポインタを先頭へ
print $fh "test!!\n";
close($fh);

こんなテストプログラムを走らせます。LOCK_SH以外は、ロックを伴うファイル操作ではよく行う処理です。

LOCK_SH(共有ロック)は本来ならLOCK_EX(排他ロック)ですが、前項で述べたとおりWindows環境ではとりあえず共有ロックで開いておいて後から排他ロックに変更できないので、そのような状況を想定してLOCK_SHで記述してあります。

さてこのプログラムを実行すると、Windows上では0byteのファイルが作成されます。ActivePerl(5.14)の問題かもしれませんが、truncateでのファイルサイズ指定がそのままclose()後のファイルサイズになります。

不思議なことに、LOCK_EX(排他ロック)に変更するときちんと中身のあるファイルが作られます。

解決策

use Fcntl;

my $fh;
sysopen($fh, "test.txt", O_CREAT | O_RDWR) or die;
flock($fh, Fcntl::LOCK_SH());

seek($fh, 0, 0);		# ファイルポインタを先頭へ
print $fh "test!!\n";

truncate($fh, tell($fh));	# 現在の位置でファイル切り詰め
close($fh);

挙動まとめ 2017/02/26

  • Windowsでは一度ロックしたものに対し、再度ロックすることができない。
    • 同じファイルハンドルを使用しても「別のロック」とみなされてしまう。
  • Linux等では同じファイルハンドルを使えば、lockは何度でもできる(状態変更できる)。

別の問題 2015/01/16

そもそもLOCK_SH(共有ロック)状態で書き換えようとすると、以前のサイズよりも大きくならず、そもそも書き変えられないという謎のバグに当たりました。

詳細な発生条件は不明ですが、めんどうくさいので、Windowsの場合共有ロックではなく最初から排他ロックをかけることにしました。

2013/08/02(金)perlでExporterを実装してみた

軽量なExporter。

  • 動作するのは @EXPORT と @EXPORT_OK
  • タグによる条件指定など複雑なエクスポートはできない

通常の使用には十分です。ただ標準の Exporter も、EXPORT変数に$や&などを付けず名前だけ使用すれば十分高速なのでボツになりました(苦笑)*1

perl の Export の原理を学ぶには良い題材だと思います。

続きを読む

2013/06/13(木)JSONを自力でパースするperlスクリプト【pure-Perl】

正しいもののみ正しくパースされるスクリプトです。

  • 外部モジュール不要。
  • 正しくないものは解析できるところまで動きます。
  • かっこ「{[」と「]}」の対応は見てません(閉じかっこの入れ違えがあっても動きます)
  • ライセンスはWTFPLですが、一言「使ったよ」ってコメントくれると嬉しいです。

バグがあったら具体的なデータと共にコメントください。

続きを読む

2012/09/28(金)Perlの型グロブと名前空間アクセスの応用

Perlの名前空間と型グロブに関する応用的な話です。高度な内容ですので、少なくともリファレンスについては理解している人向けです。型グロブも多少知らないと難しいかもしれません。

※以下特に断りがない限りPerl 5.10での動作確認です。

続きを読む