I am developing a Scala application on Windows, and I need to insert a path to a file into an HTML template. I use Java's io
and nio
to work with files and paths.
/* The paths actually come from the environment. */
val includesPath = Paths.get("foo\\inc")
val destinationPath = Paths.get("bar\\dest")
/* relativeIncludesPath.toString == "..\\foo\\inc", as expected */
val relativeIncludesPath = destinationPath.relativize(includesPath)
The problem is that the output of relativeIncludesPath.toString
contains backslashes \
as separators - because the application runs on Windows - but since the path is to be inserted into a HTML template, it must contain forward slashes /
instead.
Since I couldn't find anything like file/path.toStringUsingSeparator('/')
in the docs, I am currently helping myself with relativeIncludesPath.toString.replace('\\', '/')
, which I find rather unappealing.
Question: Is there really no better way than using replace?
I also experimented with Java's URI
, but it's relativize
is incomplete.
The path separator is a character commonly used by the operating system to separate individual paths in a list of paths.
pathSeparator: Platform dependent variable for path-separator. For example PATH or CLASSPATH variable list of paths separated by ':' in Unix systems and ';' in Windows system. File. pathSeparatorChar: Same as pathSeparator but it's char.
A file separator is a character that is used to separate directory names that make up a path to a particular location. This character is operating system specific. On Microsoft Windows, it is a back-slash character (), e.g. C:myprojectmyfilesome. properties.
If you prefer to hard-code the directory separator character, you should use the forward slash ( / ) character. It is the only recognized directory separator character on Unix systems, as the output from the example shows, and is the AltDirectorySeparatorChar on Windows.
The Windows implementation of the Path interface stores the path internally as a string (at least in the OpenJDK implementation) and simply returns that representation when toString() is called. This means that no computation is involved and there is no chance to "configure" any path separator.
For this reason, I conclude that your solution is the currently the best option to solve your problem.
I just ran into this issue. If you have a relative path, you can use the fact that Path
is an Iterable<Path>
of its elements, following an optional initial root element, and then can concatenate the pieces yourself with forward slashes. Unfortunately the root element can contain slashes, e.g. in Windows you get root elements like c:\
and \\foo\bar\
(for UNC paths), so it seems like no matter what you still have to replace with forward slashes. But you could do something like this...
static public String pathToPortableString(Path p)
{
StringBuilder sb = new StringBuilder();
boolean first = true;
Path root = p.getRoot();
if (root != null)
{
sb.append(root.toString().replace('\\','/'));
/* root elements appear to contain their
* own ending separator, so we don't set "first" to false
*/
}
for (Path element : p)
{
if (first)
first = false;
else
sb.append("/");
sb.append(element.toString());
}
return sb.toString();
}
and when I test it with this code:
static public void doit(String rawpath)
{
File f = new File(rawpath);
Path p = f.toPath();
System.out.println("Path: "+p.toString());
System.out.println(" "+pathToPortableString(p));
}
static public void main(String[] args) {
doit("\\\\quux\\foo\\bar\\baz.pdf");
doit("c:\\foo\\bar\\baz.pdf");
doit("\\foo\\bar\\baz.pdf");
doit("foo\\bar\\baz.pdf");
doit("bar\\baz.pdf");
doit("bar\\");
doit("bar");
}
I get this:
Path: \\quux\foo\bar\baz.pdf
//quux/foo/bar/baz.pdf
Path: c:\foo\bar\baz.pdf
c:/foo/bar/baz.pdf
Path: \foo\bar\baz.pdf
/foo/bar/baz.pdf
Path: foo\bar\baz.pdf
foo/bar/baz.pdf
Path: bar\baz.pdf
bar/baz.pdf
Path: bar
bar
Path: bar
bar
The textual substitution of backslash with forward slash is definitely easier, but I have no idea whether it would break some devious edge case. (Can there be backslashes in Unix paths?)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With