2009-08-22 60 views
4

我有一個以UTF-16編碼的文本文件。每行包含多個由製表符分隔的列。對於那些關心,該文件是從iTunes導出的播放列表TXT。列#27包含一個文件名。如何檢查Perl中是否存在UTF-16文件名?

我使用類似的代碼在Linux中使用Perl 5.8.8閱讀它:

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嗎?任何想法如何讓這段代碼片段工作?

+1

在我花費任何時間之前,什麼是'my $ filename =〜$ cols [26];'? – 2009-08-22 20:15:54

+0

抱歉 - 錯字。應該是=在StackOverflow錯字,而不是我原來的代碼。問題依然存在。 – blt04 2009-08-22 20:17:22

+0

文件名本身不能是UTF-16,因爲UTF-16填滿了零字節。現在許多Linux發行版正在使用UTF-8,所以這將是第一個嘗試的編碼。 – bobince 2009-08-22 20:46:47

回答

5

UTF-16文本由編碼層處理。當它進入$_時,無法告訴它它曾經是UTF-16。我不認爲這是你的問題。

我的猜測是你的文件名中有一些空格(當你試圖打印出來時你沒有注意到),或者你不在自己認爲的目錄中。

嘗試

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

,並仔細檢查文件名。您也可以use Cwd;並打印出當前目錄。

+0

謝謝cjm:我在發佈我的解決方案後看到了這個,但你是對的。 – blt04 2009-08-22 20:54:07

2

如果像你說的,實際文件名只使用ASCII字符,不會

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

工作?無論如何,xxd應該幫助你碰上這樣的事情

 
[[email protected] ~]$ 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上的時間解決你的問題的下一次。好吧。

+0

你會想。但事實並非如此。 -e仍然返回false。 只是爲了測試我的代碼的其餘部分,我試圖在Perl文件中硬編碼一個文件名,並且它工作。從iTunes UTF16文件讀取(即使使用您的空替換建議)也不起作用。 – blt04 2009-08-22 20:24:35

+0

嘗試utf8:在空替換之前降級($ filename)。 – Inshallah 2009-08-22 20:30:22

+0

@Inshalla:仍然不起作用。 – blt04 2009-08-22 20:33:14

3

我想出溶液:

柱27是最後一列,並且該文件被編碼有0D0A(\ r \ n)的行尾。 chomp只能刪除0a(\ n)。不知道爲什麼我之前沒有看到它,但它與UTF16沒有任何關係。

添加:

s/\r$//; 

格格後解決了這個問題。

感謝您的幫助 - 對不起,送你一隻兔子蹤跡。

+1

所以我說得對,這是你的文件名中的空格:-) – cjm 2009-08-22 20:54:38

+0

你也可以嘗試':crlf:encoding(UTF-16)',儘管我從來沒有試過用UTF-16的crlf,所以我不是當然,如果這有效。我只使用了:帶有單字節編碼的crlf。 – cjm 2009-08-22 20:56:21

相關問題