143

Exact Duplicate:

combine paths in java

I would like to know if there is such a method in Java. Take this snippet as example :

// this will output a/b
System.out.println(path_join("a","b"));
// a/b 
System.out.println(path_join("a","/b");
Community
  • 1
  • 1
Geo
  • 93,257
  • 117
  • 344
  • 520

4 Answers4

170

This concerns Java versions 7 and earlier.

To quote a good answer to the same question:

If you want it back as a string later, you can call getPath(). Indeed, if you really wanted to mimic Path.Combine, you could just write something like:

public static String combine (String path1, String path2) {
    File file1 = new File(path1);
    File file2 = new File(file1, path2);
    return file2.getPath();
}
Socrates
  • 8,724
  • 25
  • 66
  • 113
Daniel LeCheminant
  • 50,583
  • 16
  • 120
  • 115
  • 32
    Doesn`t work in Java 8. Better option: import java.nio.file.Paths; Path path = Paths.get(mydir, "myfile"); – Marc Wittmann May 07 '15 at 10:58
  • 12
    @MarcWittmann, what happens when you do this in Java 8? – Sam Nov 25 '15 at 10:12
  • 10
    The solution is a lot shorter with Java 7's nio: `Paths.get(path1, path2)` – Jason Yeo May 19 '16 at 07:35
  • Just note Path/Paths do not work with jar-s, only with filesystem. See eg. https://stackoverflow.com/questions/941754/how-to-get-a-path-to-a-resource-in-a-java-jar-file – Patrycja K Jul 20 '17 at 13:23
110

Try:

String path1 = "path1";
String path2 = "path2";

String joinedPath = new File(path1, path2).toString();
Dave Jarvis
  • 30,436
  • 41
  • 178
  • 315
Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
0

One way is to get system properties that give you the path separator for the operating system, this tutorial explains how. You can then use a standard string join using the file.separator.

Soviut
  • 88,194
  • 49
  • 192
  • 260
-5

This is a start, I don't think it works exactly as you intend, but it at least produces a consistent result.

import java.io.File;

public class Main
{
    public static void main(final String[] argv)
        throws Exception
    {
        System.out.println(pathJoin());
        System.out.println(pathJoin(""));
        System.out.println(pathJoin("a"));
        System.out.println(pathJoin("a", "b"));
        System.out.println(pathJoin("a", "b", "c"));
        System.out.println(pathJoin("a", "b", "", "def"));
    }

    public static String pathJoin(final String ... pathElements)
    {
        final String path;

        if(pathElements == null || pathElements.length == 0)
        {
            path = File.separator;
        }
        else
        {
            final StringBuilder builder;

            builder = new StringBuilder();

            for(final String pathElement : pathElements)
            {
                final String sanitizedPathElement;

                // the "\\" is for Windows... you will need to come up with the 
                // appropriate regex for this to be portable
                sanitizedPathElement = pathElement.replaceAll("\\" + File.separator, "");

                if(sanitizedPathElement.length() > 0)
                {
                    builder.append(sanitizedPathElement);
                    builder.append(File.separator);
                }
            }

            path = builder.toString();
        }

        return (path);
    }
}
TofuBeer
  • 60,850
  • 18
  • 118
  • 163
  • 1
    Work with the platform. As other answers show Java handles this for users, so there really is no need to roll another. – MrMesees Nov 17 '16 at 23:15
  • Because the File constructor is expensive (in terms of time). It interacts with the file system (depends on the implementation). There is no need to write code that is slower on purpose. That being said, the speed should be measured, so it is possible that my code is slower. In addition the answer I provided works for things that are not File based so it is more flexible. – TofuBeer Nov 18 '16 at 00:04
  • I'm really sorry but speed for something like this is a secondary concern, especially for a site that many people who just want to know how to do the right way are concerned. * Re implements existing Java libraries functionality * Enforces OS specific path conventions (could have been argument inject-able with default at the least) * Question is about path joining, to make it more flexible accept an interface – MrMesees Nov 18 '16 at 01:48
  • "I'm really sorry but speed for something like this is a secondary concern, especially for a site that many people who just want to know how to do the right way are concerned" that is why we have accepted answers. There is nothing technically wrong with my answer, it works, it addresses an issue (the speed), and it shows how to do the same sort of thing if it isn't files. You cannot say that speed does not matter for this, what if it is being called millions of times? – TofuBeer Nov 18 '16 at 04:28
  • " it works, it addresses an issue (the speed)" As you have mentioned above, without benchmarks we don't "know" it's faster. You brought that up, please don't tout speed without some benchmarks if that is the aim. "it shows how to do the same sort of thing if it isn't files." You use File.separator in your example, I don't see how that is portable to a wide range of non file-based systems, could you explain? – MrMesees Nov 18 '16 at 10:55
  • We also don't know it is slower. Neither one of us can make a legitimate claim about speed, save for the fact that the current JDK is "expensive" (we just don't know how expensive it is). We also don't know how frequently it will be called, so speed may or may not be a factor. Given that we don't know those things there is zero issue with providing something that works as an alternative, especially when it is more flexible (what if you wanted to use ; instead of /?) – TofuBeer Nov 18 '16 at 16:31
  • I'm not understanding your point, I was pointing out you are de-railing this into the wall by mentioning speed (you've done it lots, I tried to side-line the issue by saying "speed for something like this is a secondary concern"). If you wanted to use /? or ; to separate you could either use built in join functionality with a list (also core Java) and a delimiter. In any case it doesn't seem that you are willing to accept why so I can know I've tried to explain and we should continue on with our lives. – MrMesees Nov 21 '16 at 16:47
  • Generally speed is not a concern, write code to be correct, clear and flexible, if it is shown to be slow then loo for ways to speed it up. The code I posted is correct (or close to it, given I am not 100% sure of the requirements), it is clear (in my opinion), and is flexible (more so than the File way of doing it). It may or may not be faster, looking at the code for File there is some use of the file system which could cause a slow down. Without testing we don't know. The issue I took with speed is that you said it doesn't matter without knowing if it matters or not. – TofuBeer Nov 21 '16 at 16:57
  • My point is that you are being rather critical for an example of correct (as far as we know, nobody has said it is wrong), code. I don't mind down votes for something wrong, and I don't mind criticism/discussion. Sorry, I found your statement of "I'm really sorry but speed for something like this is a secondary concern, especially for a site that many people who just want to know how to do the right way are concerned" - what is actually wrong with the code I posted, meaning how does it technically not work? How do you know that speed does not matter? – TofuBeer Nov 21 '16 at 16:59
  • I tested the speed, I can post the code if you want. My way (stripped down of error checking to match the other way) is the fastest, on my computer, by a very small margin. I also tried String.join which did not exist when I wrote my answer, and for some reason it is also slower, which is surprisng (I need to go look at their source). So speed is not a factor here at all, but now we know. – TofuBeer Nov 21 '16 at 18:10