带有西里尔字符的文件路径的 Java java.io.filenotfoundexception
Posted
技术标签:
【中文标题】带有西里尔字符的文件路径的 Java java.io.filenotfoundexception【英文标题】:Java java.io.filenotfoundexception for file path with cyrillic characters 【发布时间】:2013-06-02 19:52:13 【问题描述】:我有一个文件,其名称不仅包含纯 ASCII 字符集的字符,还包含非 ASCII 字符集的字符。在我的例子中,它包含西里尔字符。
这是我的代码的 sn-p:
String fileName = "/Users/dnelepov/Downloads/тест изображение.png";
File sendFile = new File(fileName);
if (sendFile.exists())
// Some code
sendFile.exists
if
块中的代码没有被执行。
为什么文件无法识别?
我的系统配置 语言环境
LANG="ru_RU.UTF-8"
LC_COLLATE="ru_RU.UTF-8"
LC_CTYPE="ru_RU.UTF-8"
LC_MESSAGES="ru_RU.UTF-8"
LC_MONETARY="ru_RU.UTF-8"
LC_NUMERIC="ru_RU.UTF-8"
LC_TIME="ru_RU.UTF-8"
LC_ALL="ru_RU.UTF-8"
uname -a
Darwin Dmitrys-MacBook-Pro.local 11.4.2 Darwin Kernel Version 11.4.2: Thu Aug 23 16:25:48 PDT 2012; root:xnu-1699.32.7~1/RELEASE_X86_64 x86_64
java -version
java version "1.7.0_21"
Java(TM) SE Runtime Environment (build 1.7.0_21-b12)
Java HotSpot(TM) 64-Bit Server VM (build 23.21-b01, mixed mode)
更新
我发现这个错误是在 Oracle 的 JDK 上。
我在 Eclipse 上创建了项目,并且找到了文件。我检查了项目属性,发现 Mac OS 6 JDK。
然后我将其更改为 JDK 7,并且再次找不到文件。
我的问题是我需要将 JDK 7 与 JavaFX 一起使用。不是 Mac OS 版本。所以我的问题依然存在。
我制作了一个视频来显示这个错误 Video with error
更新 2
感谢 eumust 的回答,此代码有效:
Path path = Paths.get("/Users/dnelepov/Downloads/test/");
Files.walkFileTree(path, new SimpleFileVisitor<Path>()
@Override
public FileVisitResult visitFile(Path oneF, BasicFileAttributes attrs) throws IOException
System.out.println("FILE:" + oneF);
if (Files.exists(oneF))
System.out.println("EXISTS:" + oneF);
return FileVisitResult.CONTINUE;
);
https://***.com/a/17481204/849961
【问题讨论】:
我认为这是 Mac OS X? 是的,我要死了:( 我不喜欢这些“�”符号。你检查过你的终端的编码[可能是,Mac OS X 中的终端默认使用 ISO 8859-5 吗?看看这里的流程图:habrahabr.ru/post/147843]? 您能否在终端中输入“locale”并向我们展示它的输出(只是为了确定)? 系统配置更新问题 【参考方案1】:只是为了好玩,这个黑客可能会奏效:
String fDir = "/Users/dnelepov/Downloads/";
char[] fileName = "тест изображение.png".toCharArray();
File root = new File(fDir);
File[] folder = root.listFiles();
for (File f : folder)
if (Array.equals(fileName, f.getName().toCharArray())
//code here
...
我不知道它是否会为您带来任何不同的结果,尤其是因为它可能只是文件名的一个奇怪的编码问题,但这有助于阐明这种情况。如果代码未执行,请在 charArray 的 int (ascii vals) 上打印目录中所有文件名 - 找到您要查找的文件并查看字符的编码方式及其原因不相等。
【讨论】:
这似乎是检查它是否可以读取目录中所有文件的名称的好方法。对于每个文件,我会将结果输出到错误日志,您可以将该字符串与您正在使用的实际文件名进行比较,以找出差异。然后您将能够以某种方式处理此错误-我猜您最终将从用户交互中获取此文件?如果没有,你可以重命名文件,你能得到一个指向它在磁盘上的物理位置、大小等的指针,然后在内容中啜饮吗?或者那是不可能的,我说的是我的底线?【参考方案2】:我对非 ascii 字符也有同样的想法,这有助于(更新):
String fileName = "file:///Users/dnelepov/Downloads/тест изображение.png";
URI uri = new URI(null, null, fileName, null);
System.out.println("TS:" + uri.getPath);
System.out.println("EX:" + new File(uri).exists());
【讨论】:
String fileName = "/Users/dnelepov/Downloads/тест изображение.png";字符串 ts = new URI(fileName).getPath(); System.out.println("TS:" + ts);结果:异常 java.net.URISyntaxException:索引 30 处路径中的非法字符:/Users/dnelepov/Downloads/тест изображение.png 改用new URI(null, null, yourPath, null)
试试
没有例外,但文件对于 Java 仍然不可见
问题出在空格上,可以用%20
替换,也可以使用@fge的解决方案。我也会更新答案。
巴林特巴科,没有工作。这里更改路径: String fileName = "/Users/dnelepov/Downloads/тест%20изображение.png"; String ts = new URI(null, null, fileName, null).getPath(); System.out.println("TS:" + ts);【参考方案3】:
当我在 OSX 10.8.4 上使用 Java 7 b21 时,以下代码在 OSX 上打印为 true。根据您的内核版本,您使用的是 10.7。
import java.io.File;
public class file
public static void main(String[] args)
File file = new File("/Users/jhawk28/Developer/filetest/тест изображение.txt");
System.out.println(file.exists());
根据您包含的项目,这是我机器上的输出:
java -jar TestCyrilic.jar
EX:true
看起来这是一个在 OSX 10.8 中修复的错误。
【讨论】:
OSX:Darwin Dmitrys-MacBook-Pro.local 11.4.2 达尔文内核版本 11.4.2:2012 年 8 月 23 日星期四 16:25:48 PDT;根:xnu-1699.32.7~1/RELEASE_X86_64 x86_64 *************************************** **** Java:Java 版本“1.7.0_21”Java(TM) SE 运行时环境(构建 1.7.0_21-b12)Java HotSpot(TM) 64 位服务器 VM(构建 23.21-b01,混合模式)*** ************************ 语言环境:LANG="ru_RU.UTF-8" LC_COLLATE="ru_RU.UTF-8" LC_CTYPE="ru_RU.UTF -8" LC_MESSAGES="ru_RU.UTF-8" LC_MONETARY="ru_RU.UTF-8" LC_NUMERIC="ru_RU.UTF-8" LC_TIME="ru_RU.UTF-8" LC_ALL="ru_RU.UTF-8"跨度> 也许你应该使用带有 OS/JDK 的虚拟机,它的行为更可预测。【参考方案4】:我已经用unicode equivalents 替换了西里尔字符,它似乎对我有用:
String fileName = "/Users/user1/тест \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435.txt";
试一试
【讨论】:
字符串文件名 = "/Users/dnelepov/Downloads/test/\u0442\u0435\u0441\u0442\u0020\u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\ u0438\u0435.png"; System.out.println("EX:" + new File(fileName).exists()); - 结果 EX:false以上是关于带有西里尔字符的文件路径的 Java java.io.filenotfoundexception的主要内容,如果未能解决你的问题,请参考以下文章