18

So for example say I had it so that all of my files will be transferred from a windows machine to a unix machine as such: C:\test\myFile.txt to {somewhere}/test/myFile.txt (drive letter is irrelevant at this point).

Currently, our utility library that we wrote ourselves provides a method that does a simple replace of all back slashes with forward slashes:

public String normalizePath(String path) {
   return path.replaceAll("\\", "/");
}

Slashes are reserved and cannot be part of a file name, so the directory structure should be preserved. However, I'm not sure if there are other complications between windows and unix paths that I may need to worry about (eg: non-ascii names, etc)

MxLDevs
  • 789

5 Answers5

11

Yes, if you only do the replacement on Windows, and turn it off when running on other systems.

Doing the replacement on Unix-like systems is wrong because \ is a valid character in a file or directory name on Unix-like platforms. On these platforms, only NUL and / are forbidden in file and directory names.

Also, some Windows API functions (mostly the lower level ones) do not allow the use of forward slashes ― backslashes must be used with them.

Edit: It turns out that there are some special file systems on Windows on which / and NUL are valid characters, such as the Registry (available at \\?\GLOBALROOT\Registry from a Windows API perspective, or \Registry from the Native API perspective). In the Named Pipe File System (usually mounted at \??\pipe), all characters (including /, \, and even NUL) are valid. So in general, not only is it not valid to replace / with \ on Windows, it is not valid to assume that every Windows file can be accessed using the Windows API! To reliably access arbitrary files, one must use the Native API (NtCreateFile and friends). NtCreateFile also exposes an equivalent of openat(2), which isn’t exposed via the Windows API.

Demi
  • 826
5

Yes, but this whole thing is a moot point. Java seamlessly converts forward slashes to back slashes on Windows. You can simply use forward slashes for all paths that are hard-coded or stored in configuration and it will work for both platforms.

Personally, I always use the forward slash even on Windows because it is not the escape character. Whether the raw path is in code or externalized in a properties file, I encode it the same way.

Try it! This will work in Windows. Obviously, change the actual path to something that exists and your user has permission to read.

File f = new File("c:/some/path/file.txt");
if (!f.canRead()) {
  System.out.println("Uh oh, Snowman was wrong!");
}

Bonus: you can even mix slashes in the same path!

File f = new File("c:/some\\path/file.txt");
if (!f.canRead()) {
  System.out.println("Uh oh, Snowman was wrong again!");
}
5

Another complication on Windows is that it also supports UNC notation as well as the traditional drive letters.

A file on a remote file server can be accessed as \\server\sharename\path\filename.

Simon B
  • 9,772
2

No. There are far more things to think about than just the path separator (the "\ vs /" thing). As Rob Y mentions, there is how spaces are handled, and their high frequency in Windows usage. There are different illegal characters in the two environments. There is Unix's willingness to allow almost anything when escaped by a leading "\". There is Windows use of '"' to deal with embedded spaces. There is Windows' use of UCS-16 and Unix's use of ASCII or UTF-8.

etc., etc., etc.

But, for lots of applications that can put constraints on the pathnames they need to manipulate, you actually can do it just the way you suggest. And it will work in at least a large number of the cases, just not all of them.

1

Every Microsoft operating system, starting with MS-DOS, has understood, at the kernel level, both forward slashes and backslashes.

Therefore, on Windows, you can convert between them freely; both have equal status as reserved separators. In any valid path, you can replace backslashes with slashes and vice versa, without changing its meaning, as far as the kernel is concerned.

In early versions of DOS, Microsoft's command.com interpreter made it a configurable preference which slash was used to display and parse paths. That was eventually removed.

Some user-space programs in Windows such as, oh, the Windows shell (explorer.exe) do not like forward slashes. That's just shoddy programming in those programs.

Kaz
  • 3,692