জাভাতে কীভাবে পথ একত্রিত করবেন?


350

জাভা সমতুল্য আছে কি? System.IO.Path.Combine()সি # /। নেট এ ? বা এটি সম্পাদন করার জন্য কোনও কোড?

এই স্থিতিশীল পদ্ধতিতে এক বা একাধিক স্ট্রিংকে একটি পাথের সাথে সংযুক্ত করে।


1
এই তাই প্রশ্ন সাহায্য করতে পারে।
জিম ব্লিজার্ড

উত্তর:


407

স্ট্রিং-ভিত্তিক সবকিছু রাখার পরিবর্তে আপনার এমন একটি ক্লাস ব্যবহার করা উচিত যা ফাইল সিস্টেমের পাথ উপস্থাপনের জন্য ডিজাইন করা হয়েছে।

আপনি যদি জাভা 7 বা জাভা 8 ব্যবহার করছেন তবে আপনার ব্যবহারের জন্য দৃ strongly়ভাবে বিবেচনা করা উচিত 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। জাভা সংস্করণ নেতৃস্থানীয়কে ছাড়বে /বা \ এটিকে আপেক্ষিক পথ হিসাবে বিবেচনা করবে।
ফিনিউ

23
@ ম্যাথিউ - কারণ ডিরেক্টরি একটি ফাইল। এটি ফাইল যার বিষয়বস্তু সেই দির বাচ্চাদের সংজ্ঞা দেয়, ডিস্কে তাদের অবস্থান, অনুমতি ইত্যাদি
--óóal

7
@ হুগো: সুতরাং এটি পুরো দুটি বস্তুকে নষ্ট করে ? জঘন্য! আমার কাছে বেশ পরিষ্কার দেখাচ্ছে, সত্যি বলতে ... এটি ফাইল ক্লাসে যেখানে সম্পর্কিত সেখানে এটি সম্পর্কিত সম্পর্কিত নামগুলির জন্য যুক্তি রাখে ।
জন স্কিটি

1
@modosansreves: তাকান File.getCanonicalPath
জন স্কিটি

1
@ সার্জবার্স: ওয়েল সি # একটি ভাষা মাত্র। আপনি চাইলে সহজেই Fileসি # তে আপনার নিজের সমতুল্য তৈরি করতে পারেন । (আমি ধরে নিচ্ছি আপনার অস্তিত্বের অর্থ Fileহ'ল একটি উপকার, যার সাথে আমি একমত হব))
জন স্কিচ

118

জাভা 7 এ, আপনার ব্যবহার করা উচিত resolve:

Path newPath = path.resolve(childPath);

অপ্রয়োজনীয়ভাবে পৃথক পৃথক এপিআই দিয়ে এনআইও 2 পাথ শ্রেণিটি ফাইলকে কিছুটা রিডানড্যান্ট মনে হতে পারে তবে এটি প্রকৃতপক্ষে আরও মার্জিত এবং শক্ত।

মনে রাখবেন 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

প্রধান উত্তর হ'ল ফাইল অবজেক্ট ব্যবহার করা। তবে কমন্স আইও-তে একটি ক্লাসের ফাইলনামটিল রয়েছে যা এই জাতীয় জিনিস যেমন কনক্যাট () পদ্ধতি হিসাবে করতে পারে ।


7
ফাইলের নামUtils.concat, সুনির্দিষ্ট হতে। commons.apache.org/proper/commons-io/apidocs/org/apache/commons/…
মাইকএফএইএইচ

আপনি যদি জেএসএফ-এর মতো কিছু নিয়ে কাজ করছেন তবে আপনি অবশ্যই স্ট্রিং-ভিত্তিক রাখতে চান যে সমস্ত পাথ আপনি পাবে স্ট্রিং-ভিত্তিক।
ড্যানিয়েল

17

জনের আসল উত্তরের পর থেকে আমি এটির দীর্ঘকাল জানি, তবে ওপিতে আমার একইরকম প্রয়োজন ছিল।

জনের সমাধান বাড়ানোর পথে আমি নিম্নলিখিতটি নিয়ে এসেছি, যা এক বা একাধিক পাথ অংশ নেবে যতগুলি পথ অংশ আপনি এটি ফেলে দিতে পারেন takes

ব্যবহার

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

প্ল্যাটফর্মের স্বতন্ত্র পন্থা (ফাইল.সেস্পেটর ব্যবহার করে, অর্থাৎ কাজ করবে এমন কোড অপারেশন সিস্টেমের উপর নির্ভর করে যেখানে কোড চলছে:

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

জোডাস্টেফেনের উত্তরটি বাড়ানোর জন্য, অ্যাপাচি কমন্স আইও-তে ফাইলের নাম রয়েছে যা এটি করে। উদাহরণ (লিনাক্সে):

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();
}

2

আপনার যদি স্ট্রিংয়ের চেয়ে বেশি প্রয়োজন না হয় তবে আপনি com.google.common.io.Files ব্যবহার করতে পারেন

Files.simplifyPath("some/prefix/with//extra///slashes" + "file//name")

পেতে

"some/prefix/with/extra/slashes/file/name"

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"
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.