Difference Between File.Separator and Slash in Paths

Difference between File.separator and slash in paths

With the Java libraries for dealing with files, you can safely use / (slash, not backslash) on all platforms. The library code handles translating things into platform-specific paths internally.

You might want to use File.separator in UI, however, because it's best to show people what will make sense in their OS, rather than what makes sense to Java.

Update: I have not been able, in five minutes of searching, to find the "you can always use a slash" behavior documented. Now, I'm sure I've seen it documented, but in the absense of finding an official reference (because my memory isn't perfect), I'd stick with using File.separator because you know that will work.

/, // and File.Separator

Forward-slash works sometimes on Windows. The file system and the kernel treat '/' and '\' equivalently in path names. This has always been the case in the Windows NT line (2000, XP, Vista, 7, 8, 10) but was never true for DOS-based Windows.

Application code is not necessarily so accommodating. Code written by someone unaware of this convention may not understand '/'.

Then, too, there's the problem of command-line processing, where '/' may indicate a switch rather than a path.

So, 'Windows' itself understands '/' and '\' to be equivalent in pathnames, but not all code that runs in Windows knows that.

tl;dr - sometimes it works, sometimes it does not.

Difference between forward slash (/) and backslash (\) in file path

/ is the path separator on Unix and Unix-like systems. Modern Windows can generally use both \ and / interchangeably for filepaths, but Microsoft has advocated for the use of \ as the path separator for decades.

This is done for historical reasons that date as far back as the 1970s, predating Windows by over a decade. In the beginning, MS-DOS (the foundation to early Windows) didn't support directories. Unix had directory support using the / character since the beginning. However, when directories were added in MS-DOS 2.0, Microsoft and IBM were already using the / character for command switches, and because of DOS's lightweight parser (descended from QDOS, designed to run on lower end hardware), they couldn't find a feasible way to use the / character without breaking compatibility with their existing applications.

So, to avoid errors about "missing a switch" or "invalid switch" when passing filepaths as arguments to commands such as these:

cd/                        <---- no switch specified
dir folder1/folder2 <---- /folder2 is not a switch for dir

it was decided that the \ character would be used instead, so you could write those commands like this

cd\
dir folder1\folder2

without error.

Later, Microsoft and IBM collaborated on an operating system unrelated to DOS called OS/2. OS/2 had the ability to use both separators, probably to attract more Unix developers. When Microsoft and IBM parted ways in 1990, Microsoft took what code they had and created Windows NT, on which all modern versions of Windows are based, carrying this separator agnosticism with it.


As backward compatibility has been the name of the game for Microsoft from all of the major OS transitions that they've undertaken (DOS to Win16/DOS, to Win16/Win32, to Win32/WinNT), this peculiarity stuck, and it will probably exist for a while yet.

It's for this reason that this discrepancy exists. It should really have no effect on what you're doing because, like I said, the WinAPI can generally use them interchangeably. However, 3rd party applications will probably break if you pass a / when they expect a \ between directory names. If you're using Windows, stick with \. If you're using Unix or URIs (which have their foundation in Unix paths, but that's another story entirely), then use /.


In the context of C#: It should be noted, since this is technically a C# question, that if you want to write more "portable" C# code that works on both Unix and Windows (even if C# is predominantly a Windows language), you might want to use the Path.DirectorySeparatorChar field so your code uses the preferred separator on that system, and use Path.Combine() to append paths properly.

File separator allowed within java.io.File

Can 4 also be correct by this logic?

Given that the question is

Suppose that the file c:\book\java exists. Which of the following
lines of code creates an object that represents the file? (Choose all
that apply.)

  1. new File("c:\book\java");
  2. new File("c:\book\java");
  3. new File("c:/book/java");
  4. new File("c://book//java");
  5. None of the above

2 and 3 are obviously correct. So, does the File object in 4 "create an ojbect that represents the file"?

Yes it does.

Assuming C:\book\java exists, this code

public static void main( String[] args ) throws IOException
{
File f = new File( args[ 0 ] );
System.err.printf( "args[0]: %s\n", args[ 0 ] );
System.err.printf( "Path: %s\n", f.getCanonicalPath() );
}

produces this output:

args[0]: C://book//java
Path: C:\book\java

So new File( "C://book//java" ) most definitely "creates an object that represents the file" and is also a correct answer.

Any argument that it does not is literally incorrect. The question is whether or not the string "creates an object that represents the file". C://book//java demonstrably does exactly that.

So what IS the right direction of the path's slash (/ or \) under Windows?

A file path and a URI are different. \ is correct in a Windows file path and / is correct in a URI.

So this file path: C:\Documents\Foo translates to this URI: file:///C:/Documents/Foo

Should I care about File#separator for Path#resolve(String)

File#separator is not necessary if you want to keep your path logic platform-agnostic. An easier way to do it is to build the child path with Paths.get() and resolve that. E.g.,:

Path path = Paths.get("a", "b", "c");
Path directory = ...;

Path target = directory.resolve(path);

Java requires slash instead of backslash on Windows in resources

A resource is something on the class path, which can be considered a sort of JVM specific virtual file-system (it is comprised of all JARs and directories, etc that have been specified on the class path). The file separator for this virtual file system is exclusively /. So, just use / and you are good to go. You don't need to fiddle with File.separator or anything, as the / is already system independent.

As an aside, even on Windows, most filesystem APIs allow you to use / and \ interchangeably.



Related Topics



Leave a reply



Submit