7

I am trying to copy a file on an ubuntu machine using the java statement

Files.copy(new File("/tmp/source/测试.xlsx").toPath(), new File("/tmp/dest/测试.xlsx").toPath(), StandardCopyOption.REPLACE_EXISTING);

But i get the following error

java.nio.file.InvalidPathException: Malformed input or input contains unmappable characters: /tmp/source/测试.xlsx at sun.nio.fs.UnixPath.encode(UnixPath.java:147) ~[na:1.8.0_91] at sun.nio.fs.UnixPath.(UnixPath.java:71) ~[na:1.8.0_91] at sun.nio.fs.UnixFileSystem.getPath(UnixFileSystem.java:281) ~[na:1.8.0_91] at java.io.File.toPath(File.java:2234) ~[na:1.8.0_91]

This runs perfectly fine when i run it on my eclipse. Also, the code works fine with all english characters.

user3820369
  • 187
  • 2
  • 5
  • "_This runs perfectly fine when i run it on my eclipse_". Are you saying that it does not work when you run this program in command line ? – Pradhan May 24 '16 at 09:28
  • Does your Eclipse run on a different operating system than Ubuntu? – Erwin Bolwidt May 24 '16 at 09:34
  • @MadPiranha On my eclipse, i run it as a standalone java application and pass the parameters using main method. The project i am running on ubuntu is a maven project deployed on tomcat which is triggered using an API REST call – user3820369 May 24 '16 at 10:09
  • @ErwinBolwidt My eclipse is running on mac OS. – user3820369 May 24 '16 at 10:12

2 Answers2

8

This could be a JDK Bug

Set the following system properties sun.jnu.encoding=UTF-8 and file.encoding=UTF-8.

  • Check this to add system properties in tomcat maven plugin.
  • Use the -D option if you are running a java program in command line. (-Dsun.jnu.encoding=UTF-8 -Dfile.encoding=UTF-8)
Pradhan
  • 518
  • 4
  • 14
  • This works on Java but when running Java via the groovy binary mine seems to ignore the command line properties. Any idea why? `groovy -Dsun.jnu.encoding=UTF-8 -Dfile.encoding=UTF-8 myfile.groovy` – Sridhar Sarnobat May 20 '17 at 04:53
  • 1
    In answer to my own question, as a workaround you can use `export JAVA_OPTS="-Dfile.encoding=UTF-8"` – Sridhar Sarnobat May 20 '17 at 04:58
6

I believe it's related to the locale setting on the machine where you want to run the application.

Take folloing snippet

public class Main {
    public static void main(String[] args) throws IOException {
        Path source = Paths.get("/tmp/source/测试.xlsx");
        Path destination = Paths.get("/tmp/dest/测试.xlsx");
        Files.copy(source, destination, StandardCopyOption.REPLACE_EXISTING);
    }
}

compile

javac -encoding UTF8 Main.java

run with locale UTF8

LANG=en_US.utf8 java sub.optimal.playground.Main

The destination file will be created (assuming the directory exist and you have the right permissions).

run with locale C

LANG=C java sub.optimal.playground.Main

output

java.nio.file.InvalidPathException: Malformed input or input contains
    unmappable characters: /tmp/source/??.xlsx

Check if the session in which you want to run the application uses a locale which supports UTF8 (simple run locale).

SubOptimal
  • 22,518
  • 3
  • 53
  • 69