আমি জাভাতে কোনও ডিরেক্টরিতে থাকা ফাইলগুলির মাধ্যমে পুনরাবৃত্তি করব?


175

আমাকে একটি ডিরেক্টরিতে সমস্ত সাব ডিরেক্টরিতে ফাইল সহ সমস্ত ফাইলের একটি তালিকা পেতে হবে। জাভা দিয়ে ডিরেক্টরি পুনরাবৃত্তি সম্পন্ন করার স্ট্যান্ডার্ড উপায় কী?

উত্তর:


207

File#isDirectory()প্রদত্ত ফাইল (পাথ) ডিরেক্টরি হলে আপনি পরীক্ষা করতে ব্যবহার করতে পারেন । যদি এটি হয় trueতবে তার File#listFiles()ফলাফলের সাথে আপনি আবার একই পদ্ধতিটি কল করুন । একে পুনরাবৃত্তি বলা হয় ।

এখানে একটি বেসিক কিক অফের উদাহরণ।

public static void main(String... args) {
    File[] files = new File("C:/").listFiles();
    showFiles(files);
}

public static void showFiles(File[] files) {
    for (File file : files) {
        if (file.isDirectory()) {
            System.out.println("Directory: " + file.getName());
            showFiles(file.listFiles()); // Calls same method again.
        } else {
            System.out.println("File: " + file.getName());
        }
    }
}

নোট করুন যে StackOverflowErrorগাছটি যখন JVM এর স্ট্যাক ধরে রাখতে পারে তার চেয়ে গভীর হয় to এর পরিবর্তে আপনি পুনরাবৃত্তি পদ্ধতি বা লেজ- পুনরাবৃত্তি ব্যবহার করতে চাইতে পারেন তবে এটি অন্য বিষয়;)


ধন্যবাদ বালুস, সাধারণ অনুমান হিসাবে এটি কত গভীর হতে পারে তার কোনও ধারণা?
জেমস

10
আপনার JVM এর মেমরি সেটিংস উপর নির্ভর করে। তবে সাধারণত কয়েক হাজারের মতো কিছু। আপনি যদি ভাবেন যে আপনি কখনই এর মতো কোনও ডিরেক্টরিতে চলে যেতে পারেন তবে পুনরাবৃত্তিটি ব্যবহার করবেন না।
মাইক বারানজাক

4
এটি NullPointerExceptionকলটির মধ্যে যখন ফাইল সিস্টেমটি পরিবর্তিত হয় isDirectoryএবং ব্লক বা আপনি listFilesযদি System.out.printlnসত্যিই দুর্ভাগ্য হন তবে এমন ঘটনা ঘটতে পারে to আউটপুট listFilesনাল নয় তা যাচাই করা সেই জাতি শর্তটিকে সমাধান করবে।
মাইক স্যামুয়েল

1
@ বোরাটসাগদিয়েভ, পুরানো জাভা ফাইল এপিআইগুলি ব্যবহার করছেন না, তবে আপনি যদি একটি আধুনিক জেভিএম এ থাকেন তবে java.nio.file.DirectoryStreamআপনাকে কোনও ডিরেক্টরিতে পুনরাবৃত্তি করতে দেয় এবং একটি ছোট মেমোরির পদচিহ্ন প্রয়োগ করা যেতে পারে তবে নিশ্চিতভাবে জানার একমাত্র উপায় হ'ল একটি নির্দিষ্ট প্ল্যাটফর্মে মেমরির ব্যবহার নিরীক্ষণ করতে।
মাইক স্যামুয়েল

1
"সি: \\" ফোল্ডার উদাহরণের সেরা চয়েজ নয়)
ভায়াচ্লাভ

86

আপনি যদি জাভা 1.7 ব্যবহার করেন তবে আপনি ব্যবহার করতে পারেন java.nio.file.Files.walkFileTree(...)

উদাহরণ স্বরূপ:

public class WalkFileTreeExample {

  public static void main(String[] args) {
    Path p = Paths.get("/usr");
    FileVisitor<Path> fv = new SimpleFileVisitor<Path>() {
      @Override
      public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
          throws IOException {
        System.out.println(file);
        return FileVisitResult.CONTINUE;
      }
    };

    try {
      Files.walkFileTree(p, fv);
    } catch (IOException e) {
      e.printStackTrace();
    }
  }

}

আপনি যদি জাভা 8 ব্যবহার করেন তবে আপনি স্ট্রিম ইন্টারফেসটি এর সাথে ব্যবহার করতে পারেন java.nio.file.Files.walk(...):

public class WalkFileTreeExample {

  public static void main(String[] args) {
    try (Stream<Path> paths = Files.walk(Paths.get("/usr"))) {
      paths.forEach(System.out::println);
    } catch (IOException e) {
      e.printStackTrace();
    }
  }

}

1
যখন কোনও নতুন ডিরেক্টরি চলে এবং কোনও ফাংশন সম্পাদন করে তখন স্ট্রিমগুলির সাথে একটি চেকপয়েন্ট স্থাপনের কোনও উপায় আছে?
রঘু ডিভি

28

পরীক্ষা করে দেখুন FileUtils এ্যাপাচি কমন্স মধ্যে বর্গ - বিশেষভাবে iterateFiles :

প্রদত্ত ডিরেক্টরিতে (এবং allyচ্ছিকভাবে এর উপ-ডিরেক্টরিগুলি) ফাইলগুলির মাধ্যমে পুনরাবৃত্তির অনুমতি দেয়।


5
এই এপিআই সত্যই স্ট্রিমিং করছে না (যদি আপনি মেমো ব্যবহারের বিষয়ে চিন্তা করেন) তবে এটি প্রথমে একটি সংগ্রহ উত্পন্ন করে, তারপরেই এটির উপরে একটি পুনরাবৃত্তি প্রদান করে: রিটার্ন লিস্টফায়ালস (ডিরেক্টরি, ফাইলফিল্টার, ডায়ারফিল্টার) .iterator ();
গিলি নাচুম

জাভা 1.6 এর জন্য ভাল বিকল্প।
ডেভিড আই।

@ গিলিনাচুমের সাথে একমত অ্যাপাচি দ্বারা ফাইলUtils প্রথমে সমস্ত ফাইল সংগ্রহ করে এবং তাদের জন্য একটি পুনরাবৃত্তি দেয়। আপনার যদি প্রচুর পরিমাণে ফাইল থাকে তবে এটি সংস্থানগুলির জন্য ক্ষতিকারক।
বোগদান সাম্যান্ড্রোস

8

জাভা 7+ এর জন্যও রয়েছে https://docs.oracle.com/javase/7/docs/api/java/nio/file/DirectoryStream.html

জাভাডোক থেকে নেওয়া উদাহরণ:

List<Path> listSourceFiles(Path dir) throws IOException {
   List<Path> result = new ArrayList<>();
   try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir, "*.{c,h,cpp,hpp,java}")) {
       for (Path entry: stream) {
           result.add(entry);
       }
   } catch (DirectoryIteratorException ex) {
       // I/O error encounted during the iteration, the cause is an IOException
       throw ex.getCause();
   }
   return result;
}

8

ব্যবহার org.apache.commons.io.FileUtils

File file = new File("F:/Lines");       
Collection<File> files = FileUtils.listFiles(file, null, true);     
for(File file2 : files){
    System.out.println(file2.getName());            
} 

আপনি যদি উপ ডিরেক্টরি থেকে ফাইল না চান তবে মিথ্যা ব্যবহার করুন।


3

এটি একটি গাছ, তাই পুনরাবৃত্তি আপনার বন্ধু: পিতামাতার ডিরেক্টরিটি শুরু করুন এবং শিশু ফাইলগুলির অ্যারে পেতে পদ্ধতিটি কল করুন। চাইল্ড অ্যারের মাধ্যমে আইট্রেট করুন। যদি বর্তমান মানটি একটি ডিরেক্টরি হয় তবে এটি আপনার পদ্ধতির পুনরাবৃত্তির কলকে দিন। যদি তা না হয় তবে পাতার ফাইলটি যথাযথভাবে প্রক্রিয়া করুন।


2

যেমনটি উল্লেখ করা হয়েছে, এটি একটি পুনরাবৃত্তি সমস্যা। বিশেষত, আপনি তাকান করতে পারেন

listFiles() 

জাভা ফাইল এপিআইতে এখানে । এটি একটি ডিরেক্টরিতে সমস্ত ফাইলের একটি অ্যারে প্রদান করে। পাশাপাশি এটি ব্যবহার করে

isDirectory()

আপনার আরও পুনরাবৃত্তি প্রয়োজন কিনা তা দেখতে একটি ভাল শুরু।


উত্তরের একটিটি নষ্ট হয়ে যাওয়ার কারণে এই লিঙ্কটি কার্যকর হতে পারে।
দংলেকো

0

@ এসএমডিফোর্ড উত্তরের সাথে যুক্ত করার জন্য, ফাইল ট্রি যখন চালিত হয় আপনি বেশিরভাগ সময় ডিরেক্টরি হিসাবে কোনও ফাংশন সম্পাদন করতে বা কোনও নির্দিষ্ট ফাইল পরিদর্শন করতে চাইতে পারেন। আপনি যদি স্ট্রিমগুলি ব্যবহার করতে নারাজ হন। নিম্নলিখিত পদ্ধতিগুলি ওভাররাইড কার্যকর করা যেতে পারে

Files.walkFileTree(Paths.get(Krawl.INDEXPATH), EnumSet.of(FileVisitOption.FOLLOW_LINKS), Integer.MAX_VALUE,
    new SimpleFileVisitor<Path>() {
        @Override
        public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs)
                throws IOException {
                // Do someting before directory visit
                return FileVisitResult.CONTINUE;
        }
        @Override
        public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
                throws IOException {
                // Do something when a file is visited
                return FileVisitResult.CONTINUE;
        }
        @Override
        public FileVisitResult postVisitDirectory(Path dir, IOException exc)
                throws IOException {
                // Do Something after directory visit 
                return FileVisitResult.CONTINUE;
        }
});

0

আপনি ফাইল ট্র্যাভারসালের জন্য ফাইল.লিস্ট (ফাইলের নাম ফিল্টার) (এবং রূপগুলি) অপব্যবহার করতে পারেন। শর্ট কোড এবং প্রারম্ভিক জাভা সংস্করণগুলিতে কাজ করে, যেমন:

// list files in dir
new File(dir).list(new FilenameFilter() {
    public boolean accept(File dir, String name) {
        String file = dir.getAbsolutePath() + File.separator + name;
        System.out.println(file);
        return false;
    }
});
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.