Perl 新手第一次使用 Unicode 的经验(在文件名、-e 运算符、打开运算符和 cmd 窗口中)

2023-12-15

我有一个 Windows Perl(5.16.1 32 位)程序,它打开一个媒体文件并(使用 ffmpeg)提取音频片段 - 其目的是将单个专辑音乐曲目(包含多首歌曲)转换为多首单独的歌曲文件。

当要处理的媒体文件的名称都是 ASCII 字符时,这一切都工作得很好。 我最近针对包含俄语字符的文件名尝试了该程序,但该程序在多个方面都严重失败。

虽然这一定与 Unicode 有关,而且我以前从未需要使用 Unicode 做任何事情 - 我对我在这里遇到的失败的各个方面感到相当困惑,我也不知道解决我遇到的各种问题的方法。我现在面临。

我已将其精简到最低限度以展示问题。

如果我打开 cmd 窗口并输入“chcp”,则返回值为 437。

如果我执行“dir”命令,则会显示以下内容:

04/01/2019  11:46 AM        71,982,427 IC3PEAK альбом Сладкая.mkv
06/10/2020  10:42 PM               275 test.pl

(请注意,在我的 cmd 窗口中,俄语字符确实显示为俄语字符。)

我的“test.pl”Perl 脚本在这里:

use open ":std", ":encoding(UTF-8)";

$media = "IC3PEAK альбом Сладкая.mkv";

if (-e $media) {
   print "Media file does exist\n";
} else {
   print "Media file does NOT exist\n";
}

open(IN, $media) || die "Media file ($media) can not be opened!\n";

当此 Perl 脚本运行时,使用默认的 chcp 值 437,我得到以下输出:

Media file does NOT exist
Media file (IC3PEAK альбом Сладкая.mkv) can not be opened!

如果我在 cmd 窗口中运行“chcp 1250”,然后重新运行此 Perl 脚本,我将得到以下输出:

Media file does NOT exist
Media file (IC3PEAK Ă°Ă»ÑŒĂ±ĂÂľĂÂĽ Ă¡Ă»Ă°Ă´ĂÂşĂ°Ñ.mkv) can not be opened!

问题 1:我被告知媒体文件不存在。

问题 2:当我将媒体文件名打印到 STDOUT 时,请注意显示的文件名与我执行“dir”命令时的外观不再匹配?

谁能建议如何解决这两个问题?

PS - 请注意,当我将磁盘文件名更改为纯 ASCII 'IC3PEAK.mkv',并将 $media 变量更改为也等于'IC3PEAK.mkv'时,运行修改后的 Perl 脚本会给出:

Media file does exist

以下代码在 Windows 10 1903 中进行了测试,perl -MWin32 -e"CORE::say Win32::GetACP()"返回 ACP 1252(Win 10 北美)Win32 草莓-perl 5.30.2.1 #1 3 月 17 日星期二 03:21:32 2020 x64.

初次尝试安装cpan Win32::Unicode::File失败了t/04_print.t(Wstat:768 测试:13 失败:3)信息。

在 Google 中快速搜索导致以下结果post关于 Perl 僧侣。看起来问题是Win32::Unicode::File安装已知有一段时间了。

NOTE: ikegami指出可以强制安装模块,失败的测试可以忽略。请参阅下面他的评论。

以下测试代码确认强制安装cpan -f -i Win32::Unicode::File产生期望的结果。

use strict;
use warnings;
use feature 'say';

use utf8;

use Win32::Console;
use Win32::Unicode::File;

Win32::Console::OutputCP( 65001 );

binmode STDOUT, ':encoding(UTF-8)';
binmode STDERR, ':encoding(UTF-8)';

my $fname = 'Доброе утро Россия.mkv';
my $fh = Win32::Unicode::File->new;

open $fh, '<:encoding(UTF-8)', $fname 
    or die "Can't open $fname $!";

while( <$fh> ) {
    say;
}

close $fh;

输入文件的内容Доброе утро Россия.mkv is

Доброе утро Россия

正如上面提到的帖子中所建议的,我尝试了Win32::长路径作为备选。模块安装成功。

use strict;
use warnings;
use feature 'say';

use utf8;

use Win32::Console;
use Win32::LongPath;

Win32::Console::OutputCP( 65001 );

binmode STDOUT, ':encoding(UTF-8)';
binmode STDERR, ':encoding(UTF-8)';

my $fname = 'IC3PEAK альбом Сладкая.mkv';
my $fh;

openL \$fh, '<:encoding(UTF-8)', $fname
    or die "Can't open $fname ($^E)";

while( <$fh> ) {
    # process input
    say;
}

close $fh;

而不是真实的文件IC3PEAK альбом Сладкая.mkv测试中使用了具有以下内容的同名文本文件

Привет Москва

注意:使用openL \$fh, '<', $fname真实的mkvfile 读取文件内容

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Perl 新手第一次使用 Unicode 的经验(在文件名、-e 运算符、打开运算符和 cmd 窗口中) 的相关文章

随机推荐