sironekotoroの日記

Perl で楽をしたい

Perl つかって 8 年目でディレクトリをコピーをしようとしてハマる

ディレクトリをコピーする機会がなかった

意外なことに、いままでディレクトリのコピーをする用件がなかった。

で、ハマった。

Perl でファイルコピーと言ったら File::Copy という標準モジュール。それで事足りてきた 8 年間。

だもんで、File::Copy でディレクトリもコピーできるだろうと・・・思ったけど、うまくいかない。

「ははーん、これは先に移行先のディレクトリ 作っておけってことね」と思って先行してコピー先のディレクトリを作っておくもダメ。

Mac 上で書いて、Windows 上で動かすコードだったので、文字コードの違いかなー?

と思うも違う。むー

で、File::Copy::Recursive モジュールを使ってあっさり解決した。そうか、File::Copy でディレクトリのコピーはできんかったのか・・・できると思い込んでた。

www.nqou.net

perldoc.jp

せっかくなので Windows で日本語ファイル名・フォルダを扱う時の注意

Windows文字コードcp932 ってやつで、ファイル名やパスもこの cp932 です。

そう、ファイル名だけじゃなくて パスも cp932エンコードしてあげる必要があります。

フォルダのコピーがうまくいかない時、ちゃんとファイルを認識しているんかな?と思って -e $path ってファイルテスト演算子使ってみたのですが、みごとに認識しておりませんでした。

-e encode('cp932', $path) とすることでちゃんとファイルパスを認識してくれました。

コードにするとこんな感じです。utf8 で保存したスクリプトWindows で実行ってのを想定してます。

#!/usr/bin/env perl
use strict;
use warnings;
use utf8;

use Encode qw/encode/;
use File::Spec;

# ダブルクォーテーションだと \ をエスケープ文字と認識してしまい失敗するよ
my $path = 'D:\Desktop\新しいフォルダー (2)';

if ( -e $path ) {
    print "$path is exist\n";
}
else {
    # Windowsで実行すると、ここを通る(文字化けもする)
    print "$path is not exist\n";
}

# utf8のスクリプト上に書かれたパス(9行目)を、パス含めて cp932 でエンコード
my $cp932_path = encode( "cp932", $path );

if ( -e $cp932_path ){
    # Windowsで実行すると、ここを通る(文字化けしない)
    print "$cp932_path is exist\n";
}
else {
    print "$cp932_path is not exist\n";
}

追記

さーてバリバリ続き書いてくかー!

って思ったら、ファイルコピー失敗。おいおいなんだよー、ファイルコピーは問題ないはずだろ!・・・と思ったがこういうオチだった。

f:id:sironekotoro:20210127192645p:plain

コピー先の容量不足。

ファイルコピー道は険しい。