Table of Contents
概要
- ディレクトリを再帰的に処理するサンプル。
ソースコード
Win32::Unicode::Native 版
# ファイル名のリストアップ, ファイル名の長さ付き
use strict;
use warnings;
use utf8;
use Encode;
use Win32::Unicode::Native;
my $charsetFile = 'UTF-8';
my $fileNameOut = "FileNames.txt";
my @targetDirs = map { 'D:/' . $_; } qw(
aaa bbb ccc
);
my $prevDir = '';
open( my $OUT, '>', $fileNameOut ) or die( "$fileNameOut: $!\n" );
binmode( $OUT, ":encoding($charsetFile)" );
find( \&getName, @targetDirs );
close( $OUT );
sub getName
{
my $args = shift;
my $curFile = $args->{name};
my $curDir = $args->{dir};
if ( $prevDir ne $curDir ){
print( "$curDir\n" );
$prevDir = $curDir;
}
printf $OUT ( "%d\t%s\n", length( $curFile ), $curFile );
}
# EOF
File::Next 版
# ファイル名のリストアップ, ファイル名の長さ付き
use strict;
use warnings;
use utf8;
use Encode;
use File::Next;
use Path::Class;
use Win32;
#my $charsetConsole = 'UTF-8';
my $charsetConsole = 'CP932';
my $charsetFile = 'UTF-8';
binmode( STDIN, ":encoding($charsetConsole)" );
binmode( STDOUT, ":encoding($charsetConsole)" );
binmode( STDERR, ":encoding($charsetConsole)" );
my $fileNameOut = "FileNames.txt";
# 「RECYCLER」を拾わないように
my @targetDirs = map{ encode( $charsetConsole, 'D:/' . $_ ); } qw(
aaa bbb ccc
);
my $prevDir = '';
my $nextFiles = File::Next::files( @targetDirs );
open( my $OUT, ">:encoding($charsetFile)", encode( $charsetConsole, $fileNameOut ) )
or die( "$fileNameOut: $!\n" );
while( defined ( my $file = $nextFiles->() ) ){
# $file は CP932 エンコードかつ短いファイルネーム
my $curFile = getUtf8PathName( $file );
my $curDir = getUtf8PathName( file( $file )->dir );
if ( $prevDir ne $curDir ){
print "$curDir\n";
$prevDir = $curDir;
}
printf $OUT ( "%d\t%s\n", length( $curFile ), $curFile );
}
close( $OUT );
sub getUtf8PathName
{
my $path = shift;
$path = Win32::GetLongPathName( $path );
if ( ! Encode::is_utf8( $path ) ){
$path = decode( $charsetConsole, $path );
}
return $path;
}
# EOF
自前で再帰版
#!/usr/local/bin/perl
# カレントディレクトリ以下の全てのファイルを処理する。
recursive( '.' );
exit();
##### Subroutine
# 再帰的にコピーする
# @param[in] $sBaseDir 基準となるディレクトリ
sub recursive
{
my( $sBaseDir ) = @_;
my( @FileLists, $sFileName );
@FileLists = glob( $sBaseDir.'/*' );
foreach $sFileName ( sort( @FileLists ) ){
if ( -d $sFileName ){
# ディレクトリだったら再帰呼び出し
&recursive( $sFileName );
} elsif ( -f $sFileName ){
# ファイルだったら処理する
print( $sFileName . "\n" );
}
}
}
# EOF
リンク
-
- Windows では、「RECYCLER」のようなシステム管理フォルダにアクセスして失敗することがある。
- ロングファイルネームではなく、8.3 形式の短いファイル名を返す。
-
- GetLongPathName()