例如,给定一个空文件テスト.txt,如何制作一个名为テスト.txt.copy的副本?
我在它的第一个破解设法访问该文件并创建新的文件名,但副本生成了テã,¹ƒƒ.txt.copy.
这是我的第一次破解:
#!/usr/bin/env perl
use strict;
use warnings;
use English '-no_match_vars';
use File::Basename;
use Getopt::Long;
use File::copy;
use Win32;
my (
$output_relfilepath,) = process_command_line();
open my $fh,'>',$output_relfilepath or die $!;
binmode $fh,':utf8';
foreach my $short_basename ( glob( '*.txt') ) {
# skip the output basename if it's in the glob
if ( $short_basename eq $output_relfilepath ) {
next;
}
my $long_basename = Win32::GetLongPathName( $short_basename );
my $new_basename = $long_basename . '.copy';
print {$fh} sprintf(
"short_basename = (%s)\n" .
" long_basename = (%s)\n" .
" new_basename = (%s)\n",$short_basename,$long_basename,$new_basename,);
copy( $short_basename,$new_basename );
}
printf(
"\n%s done! (%d seconds elapsed)\n",basename( $0 ),time() - $BASETIME,);
# === subroutines ===
sub process_command_line {
# default arguments
my %args
= (
output_relfilepath => 'output.txt',);
Getoptions(
'help' => sub { print usage(); exit },'output_relfilepath=s' => \$args{output_relfilepath},);
return (
$args{output_relfilepath},);
}
sub usage {
my $script_name = basename $0;
my $usage = <<END_USAGE;
======================================================================
Test script to copy files with a UTF-8 filenames to files with
different UTF-8 filenames. This example tries to make copies of all
.txt files with versions that end in .txt.copy.
usage: ${script_name} (<options>)
options:
-output_relfilepath <s> set the output relative file path to <s>.
this file contains the short,long,and
new basenames.
(default: 'output.txt')
----------------------------------------------------------------------
examples:
${script_name}
======================================================================
END_USAGE
return $usage;
}
以下是执行后output.txt的内容:
short_basename = (BD9A~1.TXT) long_basename = (テスト.txt) new_basename = (テスト.txt.copy)
我尝试用系统调用替换File::Copy的复制命令:
my $cmd = "copy \"${short_basename}\" \"${new_basename}\"";
print `$cmd`;
和Win32 :: copyFile:
Win32::copyFile( $short_basename,'true' );
不幸的是,我在两种情况下得到了相同的结果(テã,¹ƒƒ.txt.copy).对于系统调用,打印显示1个文件已复制.正如所料.
笔记:
>我在Windows 7 Professional上通过Strawberry Perl运行Perl 5.10.0
>我使用Win32模块访问长文件名
> glob返回短文件名,我必须使用它来访问该文件
>テスト= test(tesuto)于katakana
>我读过perlunitut和The Absolute Minimum Every Software Developer Absolutely,Positively Must Know About Unicode and Character Sets (No Excuses!)
应该可以使用
Win32API::File的
CopyFileW功能,这应该包含在草莓中.我自己从未搞过Unicode文件名,所以我不确定细节.您可能需要使用
Encode手动将文件名转换为UTF-16LE(编码(‘UTF16-LE’,$filename)).