前幾天在看Ultimate_ToolBox的原始碼,從codeproject上down下來一編譯,一堆錯誤,發現是由於編譯器無法識別ISO-8859-1編碼,誤讀有關字元造成的,所以立即著手準備轉換程式源檔案編碼,google了一把,也下了兩個小軟體,但是都沒有批量轉換功能,而有這功能的又不支援從ISO-8859-1到UTF-8的轉換,於是想到從前在FreeBSD下UTF-8和GB2312互相轉換的函數的iconv庫
,我知道iconv不但是一個程式庫,而且有一個同名的應用程式能夠將檔案在兩種編碼中轉換。用這個iconv程式搭配指令碼再利用重新導向功能應該可以很輕鬆地完成批量轉換檔編碼的工作。
在實際編寫指令碼的過程中,害怕將來運行出現意外,所以並沒有將轉碼過後的檔案重新導向到源檔案上,而是指定了另外一個位置,同時為了將來對Ultimate_ToolBox整個代碼編譯的方便,對工程目錄中不用進行編碼的檔案,全部原樣拷貝到新的位置,這樣一個遞迴遍曆目錄,批量轉換檔編碼的小工具就誕生了。
附上Perl的來源程式,如果windows下有已經移植過的iconv,則搭配ActivPerl也可以運行在windows環境下。
#!/cygdrive/c/Perl/bin/perl
#######################################################
#用途: 批量轉換某檔案夾內程式源檔案的編碼,其餘檔案不變
#
#用法: $./change_codepage.pl > log.txt
#
#Author: Changhailong
#
#E-mail: hailongchang165210@gmail.com
#######################################################
use File::Find;
use File::Copy;
use File::Path/make_path/;
#在這裡指定需要轉換codepage源檔案的目錄
$source_dir="d:/temp_code/ultimate_tools";
#在這裡指定目標目錄
$destination_dir="d:/temp_code/pp";
find(/&traverse,$source_dir);
sub traverse()
{
my $file=$File::Find::name;
my $df =$file;
$df =~ s//Q$source_dir/E/$destination_dir/g;
print("source: $file/n");
print("destination:$_/n");
if(-d $_)
{
if(-e $df)#如果目錄已經存在,繼續遞迴遍曆
{
print("The directory has been exist:$df/n");
last;
}
else#如果目錄不存在,則建立目錄
{
print("It is a directory, create:$df/n");
File::Path::make_path($df);
}
}
else
{
if(//.cpp$|/.h$|/.c$|/.inl$/i)#這裡用Regex指定需要轉換編碼的檔案類型
{
my $cmd = "iconv -f ISO-8859-1 -t UTF-8 </"$file/" >/"$df/""; #將ISO-8859-1轉換為UTF-8
print "$cmd/n";
system $cmd;
}
else#若不是需要轉換編碼的檔案類型,拷貝到新的位置
{
print("copy $file to $df/n");
copy($file,$df) or die "copy failed: $!/n";
}
}
print("/n/n/n");
}