83

I know the relative path of a file and want to handle it as a File object on both Linux and Windows.

What is the best way to specify platform-independent paths in Java?

Moshe Slavin
  • 5,127
  • 5
  • 23
  • 38
jakewins
  • 963
  • 1
  • 6
  • 6

8 Answers8

130

Just use /. I've been using it for 23.5 years. Never a problem.

user207421
  • 305,947
  • 44
  • 307
  • 483
  • @ses that's what the answer is about too. I have no idea what your first sentence is supposed to mean. – user207421 May 14 '13 at 17:27
  • 1
    If I am searching for a file in /opt/template using java, is this equivalent to c://opt/template in windows? – John Alexander Betts Nov 01 '13 at 20:59
  • 7
    Would work until some new OS doesn't come up with new exotic path separator! Maybe even then it would work, if JVM can handle "/" to that specific OS path separator conversion! So, generally "/" is a safe choice, but using explicit path separator is future fool proofing. – Mohnish Jun 05 '14 at 18:35
  • @Mohnish It would still work because Java would substitute, just like it does on Windows. – user207421 Aug 14 '14 at 11:52
  • 2
    @AechoLiu That's just another SO answer. No more authoritative than this in, which is at least evidence-based. A proper citation would be from the JLS or JVM Specification or the Javadoc. – user207421 Mar 30 '16 at 09:21
  • 1
    @EJP Sorry, I read the `Update` and saw the words `Now, I'm sure I've seen it documented` in that SO answer. So I believe it should be true. I encounter this problem today and found answers in SO. And you and that SO answer help me to solve that problem. I just don't want any downvotes in this anser, beacause I know you are right. – AechoLiu Mar 30 '16 at 09:44
  • 1
    You can use `/` only in specific cases. If you need to compare different paths then you might need to convert the different separators to an unified one, in order to get the correct results. For example: `Paths.get("a/b").equals(Paths.get("a\\b"))` yields `false` result (same with compareTo method, doesn't return 0), meanwhile the following: `Paths.get("a/b").equals(Paths.get("a/b"))` returns `true`. Given this example, I strongly discourage the only use of `/` separator, since it might unexpectedly break your code interoperability between platforms. – Sipka Jul 02 '16 at 22:06
  • 2
    Other Path class methods uses the platform separator, so here: `Paths.get("a/b").resolve("c")` on Windows, will result in `a/b\c' which will work with File opening, and other use-cases, but in equality testing, still could result in unexpected bugs. – Sipka Jul 02 '16 at 22:08
  • @Spika The point is that `/` *is* the 'unified one'. Not a 'specific case'. – user207421 Jul 06 '16 at 09:28
59

The File class contains the following public members that you can use for platform specific file paths:

static String pathSeparator:
The system-dependent path-separator character, represented as a string for convenience.
static char pathSeparatorChar:
The system-dependent path-separator character.
static String separator:
The system-dependent default name-separator character, represented as a string for convenience. static char separatorChar:
The system-dependent default name-separator character.

xenoterracide
  • 16,274
  • 24
  • 118
  • 243
jjnguy
  • 136,852
  • 53
  • 295
  • 323
  • 1
    I tried using `pathSeparator` in my application, but on OS X, that's a colon (`:`). If you toss that into a file path, OS X will interpret it as a forward slash character within the folder name. ex: Instead of creating a folder named `foo` on the user's desktop, I accidentally created a folder literally named `Desktop/foo` in the user's *home* folder. Using a plain forward slash (`/`) works exactly as expected, however. – aapierce Aug 28 '15 at 16:36
  • 35
    This answer requires a better explanation. `pathSeparator` and `pathSeparatorChar` refer to the separator used in the system's `PATH` variable. The question is referring to file paths, not the `PATH` variable. Thus, `separator` and `separatorChar` should be used. – RossBille May 10 '16 at 00:34
18

You can use any path separator in Java, it will work on both Unix and Windows. If you still want to use the system path separator there is the File.separator property which will give you the right one depending on the current system.

For the root, you can use listRoots() which gives you an array of root, there will be only one element on Unix systems, and as many as you have drives on Windows.

smac89
  • 39,374
  • 15
  • 132
  • 179
Colin Hebert
  • 91,525
  • 15
  • 160
  • 151
  • pathSeparator will retrieve the platform specific separator between paths ( ';' for unix ':' for windows). I think separator is more appropriate in this case. – Jeroen Rosenberg Aug 23 '10 at 15:06
  • 2
    pathSeparator is the separator for different entries in the PATH environment variable. For the question, File.separator would be the correct choice. – Thomas Lötzer Aug 23 '10 at 15:07
  • 2
    "You can use any path separator in Java, it will work on both Unix and Windows." -- wrong. If you use backslash (\) on Unix, it will not be recognized as a file path separator, it will be interpreted as a file name (Unix file names are allowed to contain backslashes). – Neeme Praks Sep 25 '14 at 13:05
  • @ColinHebert The answer isn't right as long as it talks about path separators. – user207421 Jul 31 '16 at 02:09
10

You can use the static field File.separator to retrieve the platform specific separator character for file paths

Jeroen Rosenberg
  • 4,552
  • 3
  • 27
  • 39
4

java 7 also supports the use of Paths here

The Path is obtained by invoking the getPath method of the default FileSystem.

You then may get a file from it by calling:

File fileSystemObtainedFile = Paths.get("C:\\foo\\bar.txt").toFile();
Neuron
  • 5,141
  • 5
  • 38
  • 59
ccDict
  • 633
  • 2
  • 6
  • 17
4

Java is pretty smart about paths in File objects. I just use something like "../foo/bar" and it works in those two platforms plus MacOSX.

Steven Ourada
  • 494
  • 3
  • 10
2

Only 10 years too late.... The "It doesn't matter just use '/'" is only half true (ok, three quarters). You have to think about where your data is coming from.

If you get a path in Java, it will use '/' If you create a path in Java it will understand '/'

But what about paths that are input to your program?

Suppose I have a series of scripts that create a config (Properties) file. Suppose one of the config variables is INTERESTING_FILE, and we generate this to be a filename including path. Now suppose I want to extract the actual Filename from that, so I say

String[] filename = INTERESTING_FILE.split("/");

This will misbehave on Windows Systems, however

String[] filename = INTERESTING_FILE.split(pathSeparator);

will work (as will washing it through the Paths class).

I guess the point is, I wouldn't assume '/' is going to work in every case.

Word Rearranger
  • 1,306
  • 1
  • 16
  • 25
  • Doesn't actually answer the question. – james.garriss Dec 28 '20 at 19:16
  • 1
    @NotAJavaGuy suggests that using "/" might be a problem because then you couldn't use "split" to find the filename. I would say that using "split" is the problem here. The better approach would be ```new File(filename).getName()``` – John Jul 30 '21 at 00:43
1

Personally, I like to use the Path class from Eclipse for handling paths in general, which you can just use standalone with few modifications as it's quite isolated.

http://grepcode.com/file/repository.grepcode.com/java/eclipse.org/3.5/org.eclipse.equinox/common/3.5.0/org/eclipse/core/runtime/Path.java/?v=source

Chris Dennett
  • 22,412
  • 8
  • 58
  • 84