Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java Paths.get() strange behavior on Linux

I am currently writing some code in which I work with files a lot. I implemented all file paths processing (concatenation, normalization, etc) using the Java 7 nio classes Paths and Path. On Windows everything works as expected however on Linux the Paths class behavior seems to be broken.

For example the following code:

    System.out.println(File.separator);
    System.out.println(FileSystems.getDefault());
    Path path = Paths.get("../dir1/", "\\dir2\\file1").toAbsolutePath().normalize();
    System.out.println(path);
    if(path.toFile().exists()) {
        System.out.println(path + " exists");
    }

on Windows prints the following output:

\
sun.nio.fs.WindowsFileSystem
D:\projects\dir1\dir2\file1
true

but the same code on Linux Ubuntu 14.04 on both Java 1.7.0_79 (64 bit) and Java 1.8.0_60 (64 bit) leaves the path un-normalized:

/
sun.nio.fs.LinuxFileSystem
/home/semi/dir1/\dir2\file1

Also even if the file is at path /home/semi/dir1/dir2/file1 exists it is reported as non-existent by path.toFile().exists().

I looked a bit over LinuxFileSystem.java and WindowsFileSystem.java and it seems that on windows the path is checked for both / and \ characters (in WindowsPathParser.isSlash(char c) method). Shouldn't the Linux implementation do the same?

Is this a bug in sun.nio.fs.LinuxFileSystem implementation or am I doing something wrong?

Also do you know any alternative to make sure Linux paths are parsed and normalized correctly (without doing all the parsing manually).

like image 803
semi Avatar asked Nov 09 '22 05:11

semi


1 Answers

In Windows, / is not a valid character in a filename so any code can assume it's a wrongly typed path separator.

In Linux, just about any byte is acceptable in a filename. In your Paths.get(), you're effectively joining a path called dir1 (1 level deep) and a path called \dir2\file1 (also 1 level deep).

like image 138
Alastair McCormack Avatar answered Nov 14 '22 21:11

Alastair McCormack