0

I have a code example which creates paths like this :

    String path = System.getProperty("user.dir") + File.separator + "games" + File.separator + "game.exe";

It is irritating and difficult to type File.separator repeatedly. Is there a shorter way to create the path ? I created a custom function to do that, but I am not sure if it is the right way. Please advise.

//Ex. getPath("downloads", "games", "racing.exe") ---> \downloads\games\racing.exe
public static String getPath(String...pathFragments){
    StringBuilder sb = new StringBuilder(File.separator);

    for(int i = 0; i < pathFragments.length-1; i++){
        sb.append(pathFragments[i] + File.separator);
    }

    //Append last pathFragment.
    sb.append(pathFragments[pathFragments.length-1]);

    return sb.toString();
}
MasterJoe
  • 2,103
  • 5
  • 32
  • 58
  • 6
    [`Paths.get`](https://docs.oracle.com/javase/7/docs/api/java/nio/file/Paths.html#get(java.lang.String,%20java.lang.String...)) would be easier. – Andy Turner Aug 24 '20 at 18:30
  • See interface [`java.nio.file.Path`](https://docs.oracle.com/javase/8/docs/api/java/nio/file/Path.html) There is also a [tutorial](https://docs.oracle.com/javase/tutorial/essential/io/path.html) – Abra Aug 24 '20 at 18:30
  • 2
    In case of pure String based solution your method can be reduced to `public static String getPath(String... pathFragments){ return String.join(File.separator, pathFragments); }` – Pshemo Aug 24 '20 at 18:37
  • 1
    BTW in your original method `sb.append(pathFragments[i] + File.separator);` should be `sb.append(pathFragments[i]).append(File.separator);` to avoid `+` representing concatenation as it needs to crate yet another StringBuilder which defeats main purpose of `sb`. OR use StringJoiner with delimiter set to `File.separator` and in loop focus only on adding actual data (File.separator will be added automatically) – Pshemo Aug 24 '20 at 18:38

3 Answers3

4

First thought: Why do you bother with File.separator? Use the cross-platform system-independent file separator character / instead.

String path = System.getProperty("user.dir") + "/games/game.exe";

The only use for File.separator is if you are constructing a file path for a user interface, and want to show the path string to the user, and don't want to confuse Windows users by mixing / and \ in the path.

Second thought: Unless you have a compelling reason to work with Strings, use Paths.get. Compelling reasons include staying backwards compatible with ancient versions of Java or libraries.

// You probably don't need to add System.getProperty("user.dir")
// Relative paths are resolved against current working directory
Path path = Paths.get("games/game.exe");

Third thought: Use String.join instead of StringBuilder.append

public static String getPath(String... pathFragments) {
    return File.separator + String.join(File.separator, pathFragments);
}
Joni
  • 108,737
  • 14
  • 143
  • 193
  • Thank you. I used File.separator because of this https://stackoverflow.com/a/2417515/6648326. Why do you recommend String.join(...) instead of StringBuilder.append(...) ? – MasterJoe Aug 25 '20 at 00:23
  • Btw, is there any code which can simply find game.exe file without having to mention directory structures which I did ? – MasterJoe Aug 25 '20 at 00:37
  • 2
    String.join is better than string append because in general less code = fewer bugs, and also you'll get performance improvements for free when standard library methods are improved. As for finding a file in a directory tree, you can use a FileVisitor https://docs.oracle.com/javase/tutorial/essential/io/walk.html – Joni Aug 25 '20 at 01:02
1
String[] leafs = { "games", "game.exe" };
String path = makePath("user.dir", File.separator, leafs);
// or
String path = makePath("user.dir", File.separator, "games", "game.exe");
System.out.println(path);
    
    
public static String makePath(String property,String separator, String... leafs) {
        return System.getProperty(property) + File.separator 
                + String.join(File.separator, leafs);
}
    
WJS
  • 36,363
  • 4
  • 24
  • 39
1

You don't need a function, and once you use File or Path then File.separator should be rarely used. For example Path.of() is all you need:

Path path = Path.of(System.getProperty("user.dir"), "games", "game.exe");
System.out.println("path="+path);

Some examples use Paths.get() but that just calls Path.of(). Note that Paths.of() is for JDK11+, but Paths.get() is JDK7+.

MasterJoe
  • 2,103
  • 5
  • 32
  • 58
DuncG
  • 12,137
  • 2
  • 21
  • 33