जावा में पथ कैसे संयोजित करें?


350

क्या System.IO.Path.Combine()C # /। NET में जावा समतुल्य है ? या इसे पूरा करने के लिए कोई कोड?

यह स्थिर विधि एक या एक से अधिक स्ट्रिंग्स को एक पथ में जोड़ती है।


1
यह SO प्रश्न मदद कर सकता है।
जिम ब्लोअर

जवाबों:


408

सब कुछ स्ट्रिंग-आधारित रखने के बजाय, आपको एक वर्ग का उपयोग करना चाहिए जो फ़ाइल सिस्टम पथ का प्रतिनिधित्व करने के लिए डिज़ाइन किया गया है।

यदि आप जावा 7 या जावा 8 का उपयोग कर रहे हैं, तो आपको दृढ़ता से उपयोग करने पर विचार करना चाहिए java.nio.file.Path; Path.resolveएक पथ को दूसरे के साथ, या एक स्ट्रिंग के साथ संयोजित करने के लिए उपयोग किया जा सकता है। Pathsसहायक वर्ग भी उपयोगी है। उदाहरण के लिए:

Path path = Paths.get("foo", "bar", "baz.txt");

यदि आपको पूर्व-जावा -7 वातावरण के लिए पूरा करने की आवश्यकता है, तो आप java.io.Fileइस तरह का उपयोग कर सकते हैं :

File baseDirectory = new File("foo");
File subDirectory = new File(baseDirectory, "bar");
File fileInDirectory = new File(subDirectory, "baz.txt");

यदि आप इसे बाद में एक स्ट्रिंग के रूप में वापस चाहते हैं, तो आप कॉल कर सकते हैं getPath()। वास्तव में, यदि आप वास्तव में नकल करना चाहते हैं, तो आप Path.Combineकुछ ऐसा लिख ​​सकते हैं:

public static String combine(String path1, String path2)
{
    File file1 = new File(path1);
    File file2 = new File(file1, path2);
    return file2.getPath();
}

10
निरपेक्ष रास्तों से सावधान रहें। .NET संस्करण एक पूर्ण पथ होने पर path2(अनदेखा path1) वापस करेगा path2। जावा संस्करण अग्रणी को गिरा देगा /या \ इसे एक रिश्तेदार पथ के रूप में व्यवहार करेगा।
१w

23
@ मैथ्यू - क्योंकि एक निर्देशिका एक फ़ाइल है। यह फाइल है जिसकी सामग्री उस डायर के बच्चों को परिभाषित करती है, डिस्क पर उनका स्थान, अनुमतियां, आदि
Dónal

7
@ ह्यूगो: तो यह एक पूरी दो वस्तुओं को बर्बाद करता है ? चौंका देने वाला! मेरे लिए बहुत साफ दिखता है, ईमानदार होना ... यह फ़ाइल फ़ाइल वर्ग में रिश्तेदार फ़ाइल नामों के लिए तर्क रखता है ।
जॉन स्कीट

1
@modosansreves: देखिए File.getCanonicalPath
जॉन स्कीट

1
@ सर्जबोरश: वेल सी # एक भाषा है। Fileयदि आप चाहते हैं तो आप आसानी से C # में अपना समकक्ष बना सकते हैं । (मैं मान रहा हूं कि आपके अस्तित्व का मतलब Fileएक लाभ है, जिसके साथ मैं सहमत हूं।)
जॉन स्कीट

118

जावा 7 में, आपको उपयोग करना चाहिए resolve:

Path newPath = path.resolve(childPath);

हालांकि NIO2 Path वर्ग अनावश्यक रूप से भिन्न API के साथ फाइल करने के लिए थोड़ा बेमानी लग सकता है, यह वास्तव में सूक्ष्म रूप से अधिक सुरुचिपूर्ण और मजबूत है।

ध्यान दें कि Paths.get()(जैसा कि किसी और द्वारा सुझाया गया है) में अधिभार नहीं है Path, और ऐसा Paths.get(path.toString(), childPath)करना वैसा नहीं है resolve()। से Paths.get()डॉक्स :

ध्यान दें कि जबकि यह विधि बहुत सुविधाजनक है, इसका उपयोग करने से डिफ़ॉल्ट फाइलसिस्टम के लिए एक अनुमानित संदर्भ हो जाएगा और कॉलिंग कोड की उपयोगिता को सीमित कर दिया जाएगा। इसलिए इसका उपयोग लाइब्रेरी कोड में लचीले पुन: उपयोग के लिए नहीं किया जाना चाहिए। एक लंगर के रूप में मौजूदा पथ उदाहरण का उपयोग करने के लिए एक अधिक लचीला विकल्प है, जैसे:

Path dir = ...
Path path = dir.resolve("file");

बहन समारोह resolveउत्कृष्ट है relativize:

Path childPath = path.relativize(newPath);

42

मुख्य उत्तर फ़ाइल ऑब्जेक्ट का उपयोग करना है। हालाँकि कॉमन्स IO में एक क्लास फिलेंम यूटिल्स होता है जो इस तरह का काम कर सकता है, जैसे कि कॉन्कैट () विधि।


7
FilenameUtils.concat, सटीक होना। commons.apache.org/proper/commons-io/apidocs/org/apache/commons/...
MikeFHay

यदि आप JSF जैसी किसी चीज़ के साथ काम कर रहे हैं, तो आप निश्चित रूप से इसे स्ट्रिंग-आधारित रखना चाहते हैं क्योंकि आपके द्वारा प्राप्त किए जाने वाले सभी पथ स्ट्रिंग-आधारित होंगे।
डैनियल

17

मैं जॉन के मूल उत्तर के बारे में लंबे समय से जानता हूं, लेकिन मुझे ओपी के लिए समान आवश्यकता थी।

जॉन के समाधान के विस्तार के माध्यम से मैं निम्नलिखित के साथ आया, जो एक या एक से अधिक पथ खंडों को ले जाएगा, जितने पथ खंड आप इसे फेंक सकते हैं।

प्रयोग

Path.combine("/Users/beardtwizzle/");
Path.combine("/", "Users", "beardtwizzle");
Path.combine(new String[] { "/", "Users", "beardtwizzle", "arrayUsage" });

एक समान समस्या वाले अन्य लोगों के लिए यहां कोड

public class Path {
    public static String combine(String... paths)
    {
        File file = new File(paths[0]);

        for (int i = 1; i < paths.length ; i++) {
            file = new File(file, paths[i]);
        }

        return file.getPath();
    }
}

12

प्लेटफ़ॉर्म इंडिपेंडेंट एप्रोच (File.separator का उपयोग करता है, यानी काम करता है) ऑपरेशन सिस्टम पर निर्भर करता है जहां कोड चल रहा है:

java.nio.file.Paths.get(".", "path", "to", "file.txt")
// relative unix path: ./path/to/file.txt
// relative windows path: .\path\to\filee.txt

java.nio.file.Paths.get("/", "path", "to", "file.txt")
// absolute unix path: /path/to/filee.txt
// windows network drive path: \\path\to\file.txt

java.nio.file.Paths.get("C:", "path", "to", "file.txt")
// absolute windows path: C:\path\to\file.txt

11

JodaStephen के उत्तर को बढ़ाने के लिए, Apache Commons IO में FilenameUtils है जो ऐसा करता है। उदाहरण (लिनक्स पर):

assert org.apache.commons.io.FilenameUtils.concat("/home/bob", "work\\stuff.log") == "/home/bob/work/stuff.log"

यह प्लेटफ़ॉर्म स्वतंत्र है और आपके सिस्टम को जो भी विभाजक चाहिए, उसका उत्पादन करेगा।


2

यहाँ एक समाधान है जो कई पथ भागों और किनारे की स्थितियों को संभालता है:

public static String combinePaths(String ... paths)
{
  if ( paths.length == 0)
  {
    return "";
  }

  File combined = new File(paths[0]);

  int i = 1;
  while ( i < paths.length)
  {
    combined = new File(combined, paths[i]);
    ++i;
  }

  return combined.getPath();
}


1

पार्टी के लिए शायद देर हो गई, लेकिन मैं इस पर अपना लेना साझा करना चाहता था। मैं एक बिल्डर पैटर्न का उपयोग कर रहा हूं और आसानी से जंजीर appendकॉल की अनुमति देता हूं । इसे आसानी से Pathवस्तुओं के साथ काम करने के लिए बढ़ाया जा सकता है ।

public class Files  {
    public static class PathBuilder {
        private File file;

        private PathBuilder ( File root ) {
            file = root;
        }

        private PathBuilder ( String root ) {
            file = new File(root);
        }

        public PathBuilder append ( File more ) {
            file = new File(file, more.getPath()) );
            return this;
        }

        public PathBuilder append ( String more ) {
            file = new File(file, more);
            return this;
        }

        public File buildFile () {
            return file;
        }
    }

    public static PathBuilder buildPath ( File root ) {
        return new PathBuilder(root);
    }

    public static PathBuilder buildPath ( String root ) {
        return new PathBuilder(root);
    }
}

उपयोग का उदाहरण:

File root = File.listRoots()[0];
String hello = "hello";
String world = "world";
String filename = "warez.lha"; 

File file = Files.buildPath(root).append(hello).append(world)
              .append(filename).buildFile();
String absolute = file.getAbsolutePath();

परिणामी absoluteमें कुछ इस प्रकार होगा:

/hello/world/warez.lha

या शायद यहां तक ​​कि:

A:\hello\world\warez.lha

1

यह जावा 8 में भी काम करता है:

Path file = Paths.get("Some path");
file = Paths.get(file + "Some other path");

0

यह समाधान एक स्ट्रिंग [] सरणी से पथ के टुकड़े में शामिल होने के लिए एक इंटरफ़ेस प्रदान करता है। इसमें java.io.File.File (स्ट्रिंग माता-पिता, स्ट्रिंग बच्चा) का उपयोग किया गया है :

    public static joinPaths(String[] fragments) {
        String emptyPath = "";
        return buildPath(emptyPath, fragments);
    }

    private static buildPath(String path, String[] fragments) {
        if (path == null || path.isEmpty()) {
            path = "";
        }

        if (fragments == null || fragments.length == 0) {
            return "";
        }

        int pathCurrentSize = path.split("/").length;
        int fragmentsLen = fragments.length;

        if (pathCurrentSize <= fragmentsLen) {
            String newPath = new File(path, fragments[pathCurrentSize - 1]).toString();
            path = buildPath(newPath, fragments);
        }

        return path;
    }

तो आप बस कर सकते हैं:

String[] fragments = {"dir", "anotherDir/", "/filename.txt"};
String path = joinPaths(fragments);

यह दिखाता है:

"/dir/anotherDir/filename.txt"
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.