我在使用Java的linux系统上遇到了一个文件读取(或许还有写入)的问题。我的应用程序抱怨它不能读取一些音频文件,当我在系统上查看时,我发现 ls -l
在这些文件上也失败了,所有的问题文件都是含有引号等字符的文件,如 é
,没有这些字符的文件也可以。
[root@N1-0247 Georges Bizet- Suites from Carmen & L'arlésienne]# pwd
/mnt/disk1/share/import/all/MusicUnmatched/WAV/Yan Pascal Tortelier/Georges Bizet- Suites from Carmen & L'arlésienne
[root@N1-0247 Georges Bizet- Suites from Carmen & L'arlésienne]# ls -l
ls: cannot access 20 - L' Arlésienne, suite for orchestra No. 1, from the incidental music- Farandole.WAV: No such file or directory
ls: cannot access 19 - L' Arlésienne, suite for orchestra No. 1, from the incidental music- Minuetto.WAV: No such file or directory
ls: cannot access 18 - L' Arlésienne, suite for orchestra No. 1, from the incidental music- Intermezzo.WAV: No such file or directory
ls: cannot access 17 - L' Arlésienne, suite for orchestra No. 1, from the incidental music- Pastorale.WAV: No such file or directory
ls: cannot access 16 - L' Arlésienne, suite for orchestra No. 1, from the incidental music- Carillon.WAV: No such file or directory
ls: cannot access 15 - L' Arlésienne, suite for orchestra No. 1, from the incidental music- Adagietto.WAV: No such file or directory
ls: cannot access 14 - L' Arlésienne, suite for orchestra No. 1, from the incidental music- Minuetto.WAV: No such file or directory
ls: cannot access 13 - L' Arlésienne, suite for orchestra No. 1, from the incidental music- Prélude.WAV: No such file or directory
ls: cannot access 08 - Carmen Suites for orchestra Nos. 1 & 2 (assembled by Ernest Guirard)- Chanson Du Toréador (Act II).WAV: No such file or directory
ls: cannot access 07 - Carmen Suites for orchestra Nos. 1 & 2 (assembled by Ernest Guirard)- Dans Bohème (Gypsy Song, Act II).WAV: No such file or directory
ls: cannot access 05 - Carmen Suites for orchestra Nos. 1 & 2 (assembled by Ernest Guirard)- Seguédille (Act I).WAV: No such file or directory
ls: cannot access 04 - Carmen Suites for orchestra Nos. 1 & 2 (assembled by Ernest Guirard)- Habeñera (Act I).WAV: No such file or directory
ls: cannot access 02 - Carmen Suites for orchestra Nos. 1 & 2 (assembled by Ernest Guirard)- Prélude (Prelude To Act I).WAV: No such file or directory
ls: cannot access 01 - Carmen Suites for orchestra Nos. 1 & 2 (assembled by Ernest Guirard)- Les Toréadors (Introduction To Act I).WAV: No such file or directory
total 192148
?????????? ? ? ? ? ? 01 - Carmen Suites for orchestra Nos. 1 & 2 (assembled by Ernest Guirard)- Les Toréadors (Introduction To Act I).WAV
?????????? ? ? ? ? ? 02 - Carmen Suites for orchestra Nos. 1 & 2 (assembled by Ernest Guirard)- Prélude (Prelude To Act I).WAV
-rw-rw-rw- 1 root root 36681194 Feb 21 2017 03 - Carmen Suites for orchestra Nos. 1 & 2 (assembled by Ernest Guirard)- La Grade Montante (Street Urchins' Chorus, Act I).WAV
?????????? ? ? ? ? ? 04 - Carmen Suites for orchestra Nos. 1 & 2 (assembled by Ernest Guirard)- Habeñera (Act I).WAV
?????????? ? ? ? ? ? 05 - Carmen Suites for orchestra Nos. 1 & 2 (assembled by Ernest Guirard)- Seguédille (Act I).WAV
-rw-rw-rw- 1 root root 16455464 Feb 21 2017 06 - Carmen Suites for orchestra Nos. 1 & 2 (assembled by Ernest Guirard)- Les Dragons D'Alcala (Entr'acte, Act II).WAV
?????????? ? ? ? ? ? 07 - Carmen Suites for orchestra Nos. 1 & 2 (assembled by Ernest Guirard)- Dans Bohème (Gypsy Song, Act II).WAV
?????????? ? ? ? ? ? 08 - Carmen Suites for orchestra Nos. 1 & 2 (assembled by Ernest Guirard)- Chanson Du Toréador (Act II).WAV
-rw-rw-rw- 1 root root 27743402 Feb 21 2017 09 - Carmen Suites for orchestra Nos. 1 & 2 (assembled by Ernest Guirard)- Intermezzo (Entr'acte, Act III).WAV
-rw-rw-rw- 1 root root 39886886 Feb 21 2017 10 - Carmen Suites for orchestra Nos. 1 & 2 (assembled by Ernest Guirard)- Marche Des Contrebandiers (Introduction To Act III).WAV
-rw-rw-rw- 1 root root 52822606 Feb 21 2017 11 - Carmen Suites for orchestra Nos. 1 & 2 (assembled by Ernest Guirard)- Nocturne (Micaela's Aria, Act III).WAV
-rw-rw-rw- 1 root root 23100378 Feb 21 2017 12 - Carmen Suites for orchestra Nos. 1 & 2 (assembled by Ernest Guirard)- Argonaise (Entr'acte, Act IV).WAV
?????????? ? ? ? ? ? 13 - L' Arlésienne, suite for orchestra No. 1, from the incidental music- Prélude.WAV
?????????? ? ? ? ? ? 14 - L' Arlésienne, suite for orchestra No. 1, from the incidental music- Minuetto.WAV
?????????? ? ? ? ? ? 15 - L' Arlésienne, suite for orchestra No. 1, from the incidental music- Adagietto.WAV
?????????? ? ? ? ? ? 16 - L' Arlésienne, suite for orchestra No. 1, from the incidental music- Carillon.WAV
?????????? ? ? ? ? ? 17 - L' Arlésienne, suite for orchestra No. 1, from the incidental music- Pastorale.WAV
?????????? ? ? ? ? ? 18 - L' Arlésienne, suite for orchestra No. 1, from the incidental music- Intermezzo.WAV
?????????? ? ? ? ? ? 19 - L' Arlésienne, suite for orchestra No. 1, from the incidental music- Minuetto.WAV
?????????? ? ? ? ? ? 20 - L' Arlésienne, suite for orchestra No. 1, from the incidental music- Farandole.WAV
我想文件系统是UTF8的,至少在我设置了
export LANG=en_US.UTF-8
在我的配置文件中,文件名显示为正确的名称。
早些时候,这些文件被Java应用程序重命名为新的名称,所以虽然报告了错误,似乎可能是Java应用程序的一些问题,但我不知道是什么。
在我的Java启动脚本中,我有以下一行
export LC_ALL=en_US.UTF-8
我在其他linux系统或Windows、MacOS ecetera上没有遇到过这个问题。
尝试声明 -Dfile.encoding=UTF-8
在你的java start命令中。
首先,有两点。
1) 事实上,你在使用 ls
显示问题是文件名和文件系统之间的问题,而不是Java本身的问题。 无论你的程序是用什么语言编写的,你都会遇到同样的问题--事实上,如果你试图直接在命令行上复制或重命名一个文件。
2) 问题不在于引号字符,因为引号字符出现在正确命名的文件中--例如.NET文件。
-rw-rw-rw- 1 root root 52822606 Feb 21 2017 11 - Carmen Suites for orchestra Nos. 1 & 2 (assembled by Ernest Guirard)- Nocturne (Micaela's Aria, Act III).WAV
所以,问题出在unicode字符é上。
这个字符就是这个 : https:/www.compart.comenunicodeU+00E9 所以它由一个空字节和E9组成。
问题是像xfs这样的POSIX文件系统不允许在文件名中使用空字节(参见 XFS文件系统中的非法字符都有哪些? )
最重要的是,你不能在那个文件系统中使用带有该字符的文件名。
所以,你必须改变文件名或文件系统。
例如,这个页面列出了文件系统,表明那些允许在文件名中使用unicode的系统。
https:/en.wikipedia.orgwikiFilename#Comparison_of_filename_limitations(比较文件名限制)。
顺便说一下,在该列表中是苹果的HFS+,但有趣的是,它已经被苹果文件系统APFS所取代,APFS不允许在文件名中使用unicode ----------。https:/developer.apple.comlibraryarchivedocumentationFileManagementConceptualAPFS_GuideFAQFAQ.html。 )
另一种选择是修改你的Java程序,修改文件名以e代替é。
String safeFilename = filename.replaceAll("é", "e");
或者如果你喜欢的话,也可以用.E代替。
String safeFilename = filename.replaceAll( "\u00e9", "e" );
这是个不错的挑战,因为这很难调试。
我试着用java.nio.Files with Java 11在Debian 10上用XFS和bash(作为ls builtin)重现,但无法重现名为é的文件的问题。
请试着去找一个更简单的重现方案和更多的细节,否则我只能猜测这可能与。
问题还在于,这似乎很难调试,因为简单的工具如 strace
在文件名的字节上没有显示足够的信息 getdents
syscall来查看低层API的情况,见。我的意思是
也许是时候换一种策略了?试着只把歌曲的全名写到一个 播放列表文件 总会有一些特殊的字符在某些环境下会引起问题,如果你不小心,甚至是脚本的空格,目录的分隔符(斜线或反斜线)等(见。这个相关问题 )
你的文件系统损坏了--这不是应用程序级别的问题,而是根据将物理磁盘内容转换为文件名+数据的文件系统驱动程序,你的物理磁盘上的内容是无效的。你需要检查哪个设备代表你的文件系统("mount "命令显示哪个设备被挂载到哪个目录--可能是类似于 /dev/sda1
. 你需要把它重新挂载为只读(如果这是你的根文件系统,这可能会很棘手),然后执行 fsck /dev/sda1
或你的设备是什么)来修复它。也不能100%确定你能找回这些文件。