Как я могу проверить наличие имен файлов UTF-16 в Perl? - PullRequest
4 голосов
/ 23 августа 2009

У меня есть текстовый файл в кодировке UTF-16. Каждая строка содержит количество столбцов, разделенных вкладками. Для тех, кому все равно, файл представляет собой плейлист TXT экспорта из iTunes. Столбец № 27 содержит имя файла.

Я читаю его, используя Perl 5.8.8 в Linux, используя код, подобный следующему:

binmode STDIN, ":encoding(UTF-16)";
while(<>)
{
    chomp;
    my @cols = split /\t/, $_;
    my $filename = $cols[26];   # Column #27 contains the filename
    print "File exists!" if (-e "$filename");
}

(Обратите внимание: я сократил этот фрагмент кода. В моем реальном коде я делаю некоторые замены, чтобы преобразовать абсолютное имя файла Windows, используемое iTunes, в имя файла, допустимое на моем Linux-компьютере)

Даже если файлы существуют, проверка файла (-e) не возвращает true. Я полагаю, что это как-то связано со строкой в ​​UTF-16, но не могу понять, в чем проблема. Фактическое имя файла использует только символы ASCII. И имя файла печатается правильно, если я печатаю переменную $ filename.

Могут ли имена файлов в Perl быть в UTF16? Любые идеи, как заставить этот фрагмент кода работать?

Ответы [ 3 ]

5 голосов
/ 23 августа 2009

Текст UTF-16 обрабатывается слоем: encoding. К тому времени, когда он попадет в $_, уже невозможно будет сказать, что это был UTF-16. Я не думаю, что это твоя проблема.

Полагаю, в вашем имени файла есть пробелы (которые вы не заметили, когда пытались распечатать), или вы не в том каталоге, который вам кажется.

Попробуйте

if (-e $filename) { print "File exists!" } 
else { print "File <$filename> not found" }

и внимательно проверьте имя файла. Вы также можете use Cwd; и распечатать текущий каталог.

3 голосов
/ 23 августа 2009

Я разобрался с решением:

Столбец 27 является последним столбцом, и файл закодирован 0d0a (\ r \ n) окончаниями строки. chomp только удалял 0a (\ n). Не знаю, почему я этого раньше не видел, но это не имеет никакого отношения к UTF16.

Добавление:

s/\r$//;

после того, как chomp исправит проблему.

Спасибо за вашу помощь - извините, что отправил вас по кроличьей тропе.

2 голосов
/ 23 августа 2009

Если, как вы говорите, фактическое имя файла использует только символы ASCII, не будет

$filename =~ s/\0//g;

работа? В любом случае, xxd должно помочь в следующий раз, когда вы столкнетесь с чем-то вроде этого

[sinan@archardy ~]$ xxd /mnt/c/Documents\ and\ Settings/sinan/Desktop/test.txt
0000000: fffe 2f00 6800 6f00 6d00 6500 2f00 7300  ../.h.o.m.e./.s.
0000010: 6900 6e00 6100 6e00 2f00 7400 6500 7300  i.n.a.n./.t.e.s.
0000020: 7400 6d00 6500 2e00 7400 7800 7400 0d00  t.m.e...t.x.t...
0000030: 0a00                                     ..

Я вижу, что вы решили свою проблему за то время, которое у меня ушло на создание тестового файла и перезагрузку в Linux. Ну хорошо.

...