17

I have a file whose name contains characters not only from the plain ASCII character set, but also from a non-ASCII character set. In my case it contains Cyrillic characters.

Here's a snippet of my code:

String fileName = "/Users/dnelepov/Downloads/тест изображение.png";
File sendFile = new File(fileName);
if (sendFile.exists()) {
    // Some code
}

The code in sendFile.exists if block is not being executed.

Why isn't the file recognized?

My system configuration locale

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)

UPDATE

I found that this error is on JDK from Oracle.

I created project on Eclipse, and file was found. I checked project properties and found Mac OS 6 JDK.

Then I change it to JDK 7 and file was not Found again.

My problem is that I need to use JDK 7 with JavaFX. Not Mac OS version. So my problem still exists.

I've made a video to show this error Video with error

UPDATE 2

Thanks to eumust for answer, this code works:

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://stackoverflow.com/a/17481204/849961

Community
  • 1
  • 1
Dmitry Nelepov
  • 7,246
  • 8
  • 53
  • 74

4 Answers4

5

Just for kicks, this hack might work:

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
          ...
    }

I don't know if it will yield any different results for you, especially since it may be just a weird encoding issue with the file name, but this could help shed some light on the situation. If the code doesn't execute, do a print on the int (ascii vals) of the charArray for all of the file names in the directory -- find the one you're looking for and see how the chars are encoded and why it's not equal.

Eric Wich
  • 1,504
  • 10
  • 8
  • This seems like a nice way to check that it can read the names of all the files in the directory. For each file I would output the result to the error log, and you can compare that string to the actual file name you are using, to find the differences. Then you'll be able to handle this error somehow - i'm guessing that ultimately you will be getting this file from user interaction? if not, can you just rename the file, could you get a pointer to its physical location on disk, size etc, then slurp in the contents ? or is that not possible and I'm talking out of my bottom ? – DaveM Jun 14 '13 at 10:50
2

I had the same with non-ascii chars and this helped (updated):

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());
Balint Bako
  • 2,500
  • 1
  • 14
  • 13
  • String fileName = "/Users/dnelepov/Downloads/тест изображение.png"; String ts = new URI(fileName).getPath(); System.out.println("TS:" + ts); Result: Exception java.net.URISyntaxException: Illegal character in path at index 30: /Users/dnelepov/Downloads/тест изображение.png – Dmitry Nelepov Jun 06 '13 at 17:27
  • 1
    Try with `new URI(null, null, yourPath, null)` instead – fge Jun 06 '13 at 17:29
  • No exception, but file still invisible for Java – Dmitry Nelepov Jun 06 '13 at 17:33
  • 1
    The problem is with the space, so you can either replace it with `%20` or you can use the the solution of @fge. I'll update the answer too. – Balint Bako Jun 06 '13 at 17:33
  • Balint Bako, no work. Here change path: String fileName = "/Users/dnelepov/Downloads/тест%20изображение.png"; String ts = new URI(null, null, fileName, null).getPath(); System.out.println("TS:" + ts); – Dmitry Nelepov Jun 06 '13 at 17:34
  • @DmitryNelepov DO NOT use "%20" if you use the `URI` constructor -- it will take care of encoding for you – fge Jun 06 '13 at 17:38
  • I also meant use this or that, not both – Balint Bako Jun 06 '13 at 17:39
  • I dont understand, can you edit answer to complete code of:String fileName = "/Users/dnelepov/Downloads/тест%20изображение.png"; String ts = new URI(null, null, fileName, null).getPath(); System.out.println("TS:" + ts); – Dmitry Nelepov Jun 06 '13 at 17:40
  • `String fileName = "/Users/dnelepov/Downloads/тест изображение.png"; String ts = new URI(null, null, fileName, null).getPath(); System.out.println("TS:" + ts);` – Balint Bako Jun 06 '13 at 17:42
  • You might have to add a `file://` prefix to the path, so it will be `String fileName = "file:///Users/dnelepov/Downloads/тест изображение.png";` (yes, 3 slashes after the `file`) – Balint Bako Jun 06 '13 at 17:46
  • And result: run: TS:/Users/dnelepov/Downloads/тест изображение.png EX:false – Dmitry Nelepov Jun 07 '13 at 08:47
  • That's odd, it's working for me with other non-ascii chars (I can't create the exact same file as in you example). I assume the file is there, isn't it? – Balint Bako Jun 07 '13 at 14:15
2

The following code prints true on OSX when I am using Java 7 b21 with OSX 10.8.4. Based on your Kernel version it looks like you are using 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());
    }
}

Based on your included project, this is the output on my machine:

java -jar TestCyrilic.jar 
EX:true

It looks like it is a bug that was fixed in OSX 10.8.

Joshua
  • 26,234
  • 22
  • 77
  • 106
  • OSX: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: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) *************************** Locale: 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" – Dmitry Nelepov Jun 08 '13 at 18:22
  • Maybe you just should use virtual machine with OS/JDK which will behave more predictable. – Maxim Kolesnikov Jun 13 '13 at 21:32
2

I have replaced cyrillic characters with unicode equivalents and it seems to work for me:

String fileName = "/Users/user1/тест \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435.txt";

Give it a shot

Chris
  • 5,584
  • 9
  • 40
  • 58
  • String fileName = "/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()); - result EX:false – Dmitry Nelepov Jun 09 '13 at 17:11