0

I use the following code to compare two Paths in Java:

import java.nio.file.Paths;

public class PathTest {
   public static void main(String args[]) {
      String path1 = "path1\\file1.jpg";
      String path2 = "path1/file1.jpg";
      System.out.println(Paths.get(path1));
      System.out.println(Paths.get(path2));
      System.out.println(Paths.get(path1).equals(Paths.get(path2)));
   }
}

I do get the following output on my Windows machine:

path1\file1.jpg
path1\file1.jpg
true

And on linux:

path1\file1.jpg
path1/file1.jpg
false

What's going on here?

flo
  • 3
  • 2
  • 1
    "Whether or not two path are equal depends on the file system implementation". Windows is just more forgiving than linux here. https://learn.microsoft.com/en-us/dotnet/standard/io/file-path-formats "All forward slashes (/) are converted into the standard Windows separator, the back slash (\)." – Jems Jan 22 '21 at 13:26
  • Yes, you're right. And the printing of the Strings was also stupid. I wanted to print the path objects and I will adjust the example. On Windows a conversion does take place of the slashes. Thanks! – flo Jan 22 '21 at 13:39

3 Answers3

1

Path separator is different for Windows and Linux.

For Windows is \

For Linux is /

Safe way in java of building paths that work on both evironments is

Path filePath = Paths.get("path1", "path2");

In your case you use a String to form a Path. So in Windows

 String path2 = "path1/file1.jpg";
 Paths.get(path2)  -> results in "path1\file1.jpg"

It converts the separator / to a windows separator \

After that conversion both path1 and path2 are the same

Now when you run in Linux the following code

      String path1 = "path1\\file1.jpg"; -> this will not be ok for linux and also will not try to convert it to / as the first \ is an escape character
      String path2 = "path1/file1.jpg";  -> this will be ok for linux /
      System.out.println(Paths.get(path1));
      System.out.println(Paths.get(path2));
      System.out.println(Paths.get(path1).equals(Paths.get(path2)));
Panagiotis Bougioukos
  • 15,955
  • 2
  • 30
  • 47
  • In the end my goal is to compare path strings that come from unix or windows systems from imported data that I have no control of. So building the Path with Paths.get("", "") isn't an option. What would be the best option here, replacing all the slashes within the strings before comparing them? – flo Jan 22 '21 at 13:58
  • Ok, I checked out https://stackoverflow.com/questions/1697303/is-there-a-java-utility-which-will-convert-a-string-path-to-use-the-correct-file And thanks a lot for helping me out! – flo Jan 22 '21 at 14:13
1

/ is the path separator on Unix and Unix-like systems like Linux. Modern Windows operating systems can use both \ and / as path separator.

anmatika
  • 1,581
  • 3
  • 21
  • 29
-1

If you develop for Windows and Linux you can generally use / as a path separator and don't bother using File.separator. For example Java on Windows resolves all these pathnames correctly without "\\" in a String, even UNC format:

var unc =  Path.of("//storage/media/camera");
// ==> \\storage\media\camera
var mdrive = Path.of("M:/camera");
// ==> M:\camera
var build = Path.of("build/classes");
// ==> build\classes
var a= Path.of("/Temp");
// ==> \Temp
DuncG
  • 12,137
  • 2
  • 21
  • 33
  • Your examples look like Groovy, not Java. Maybe for this example, the outputs would be the same. Still, since it's a Java question I think it'd be better to write your examples using Java syntax. – Brandin May 12 '22 at 06:57
  • @Brandin If you are using an older pre-JDK9 substitute `Paths.get` for `Path.of` and `Path` in place of `var`. See also how to use [jshell](https://docs.oracle.com/en/java/javase/18/jshell/introduction-jshell.html) which I used here to demonstrate the statements needed. – DuncG May 12 '22 at 08:46