CodeGym /Java Blog /এলোমেলো /জাভা ফাইল, পথ
John Squirrels
লেভেল 41
San Francisco

জাভা ফাইল, পথ

এলোমেলো দলে প্রকাশিত
ওহে! আজ আমরা ফাইল এবং ডিরেক্টরি নিয়ে কাজ করার বিষয়ে কথা বলব। আপনি ইতিমধ্যেই জানেন কিভাবে ফাইলের বিষয়বস্তু পরিচালনা করতে হয়: আমরা এটির জন্য অনেক পাঠ উৎসর্গ করেছি :) আমি মনে করি আপনি এই উদ্দেশ্যে ব্যবহৃত কয়েকটি ক্লাস মনে রাখা সহজ বলে মনে করেন। আজকের পাঠে, আমরা ফাইল পরিচালনা সম্পর্কে বিশেষভাবে কথা বলব: তৈরি করা, নাম পরিবর্তন করা ইত্যাদি। জাভা 7 এর আগে, এই ধরনের সমস্ত ক্রিয়াকলাপ ফাইল ক্লাস ব্যবহার করে সম্পাদিত হত। আপনি এখানে এটি সম্পর্কে পড়তে পারেন . কিন্তু জাভা 7-এ, ভাষার নির্মাতারা ফাইল এবং ডিরেক্টরিগুলির সাথে আমরা কীভাবে কাজ করি তা পরিবর্তন করার সিদ্ধান্ত নিয়েছে। এটি ঘটেছে কারণ ফাইল ক্লাসের বেশ কয়েকটি ত্রুটি ছিল। উদাহরণস্বরূপ, এটিতে কপি() পদ্ধতি ছিল না , যা আপনাকে একটি ফাইলকে এক অবস্থান থেকে অন্য স্থানে অনুলিপি করতে দেয় (একটি আপাতদৃষ্টিতে প্রয়োজনীয় ক্ষমতা)। উপরন্তু, দফাইল ক্লাসে বেশ কয়েকটি পদ্ধতি ছিল যা বুলিয়ান মান ফিরিয়ে দেয়। যখন একটি ত্রুটি আছে, এই ধরনের একটি পদ্ধতি মিথ্যা ফেরত. এটি একটি ব্যতিক্রম নিক্ষেপ করে না, এটি ত্রুটি সনাক্ত করা এবং তাদের কারণ নির্ণয় করা খুব কঠিন করে তোলে। একক ফাইল ক্লাসের জায়গায় , 3টি ক্লাস উপস্থিত হয়েছে: পাথ , পাথ এবং ফাইল । ঠিক আছে, সুনির্দিষ্টভাবে বলতে গেলে, পাথ একটি ইন্টারফেস, একটি ক্লাস নয়। আসুন তারা একে অপরের থেকে কীভাবে আলাদা এবং কেন আমাদের তাদের প্রত্যেকের প্রয়োজন তা খুঁজে বের করা যাক। এর সবচেয়ে সহজ দিয়ে শুরু করা যাক: পথ

পথ

পাথগুলি একটি একক স্ট্যাটিক পদ্ধতি সহ একটি খুব সাধারণ ক্লাস: get() । এটি শুধুমাত্র পাস করা স্ট্রিং বা URI থেকে একটি পাথ অবজেক্ট পেতে তৈরি করা হয়েছিল । এটির অন্য কোন কার্যকারিতা নেই। এখানে কর্মক্ষেত্রে এটির একটি উদাহরণ রয়েছে:

import java.nio.file.Path;
import java.nio.file.Paths;

public class Main {

   public static void main(String[] args) {

       Path testFilePath = Paths.get("C:\\Users\\Username\\Desktop\\testFile.txt");
   }
}
সবচেয়ে জটিল ক্লাস না, তাই না? :) ওয়েল, আমরা এই পথ টাইপ পেয়েছেন. আসুন জেনে নেই পথ কী এবং কেন এটি প্রয়োজন :)

পথ

পাথ , বাই এবং বৃহৎ, ফাইল ক্লাসের একটি নতুন ডিজাইন করা অ্যানালগ । ফাইলের চেয়ে এটি দিয়ে কাজ করা অনেক সহজ । প্রথমত , অনেক ইউটিলিটি (স্ট্যাটিক) পদ্ধতি বের করে ফাইল ক্লাসে সরানো হয়েছিল। দ্বিতীয়ত , পাথ ইন্টারফেসের পদ্ধতির রিটার্ন মানগুলির উপর আদেশ আরোপ করা হয়েছিল । ফাইল ক্লাসে , পদ্ধতিগুলি হয় একটি স্ট্রিং , বা একটি বুলিয়ান বা একটি ফাইল প্রদান করে । এটা বের করা সহজ ছিল না। উদাহরণস্বরূপ, একটি getParent() পদ্ধতি ছিল যা বর্তমান ফাইলের মূল পাথ প্রতিনিধিত্বকারী একটি স্ট্রিং প্রদান করে। কিন্তু একটি ছিলgetParentFile() পদ্ধতি, যা একই জিনিস ফিরিয়ে দিয়েছে কিন্তু একটি ফাইল অবজেক্ট আকারে! এই স্পষ্টভাবে অপ্রয়োজনীয়. তদনুসারে, পাথ ইন্টারফেসে, getParent() পদ্ধতি এবং ফাইলগুলির সাথে কাজ করার জন্য অন্যান্য পদ্ধতিগুলি কেবল একটি পাথ অবজেক্ট ফেরত দেয়। বিকল্পের কোন গাদা নেই - সবকিছু সহজ এবং সহজ। পথ আছে যে দরকারী পদ্ধতি কিছু কি কি ? এখানে তাদের কিছু এবং তারা কিভাবে কাজ করে তার উদাহরণ:
  • getFileName() : পাথ থেকে ফাইলের নাম ফেরত দেয়;

  • getParent() : বর্তমান পথের "অভিভাবক" ডিরেক্টরি প্রদান করে (অন্য কথায়, ডিরেক্টরি ট্রিতে অবিলম্বে উপরে অবস্থিত ডিরেক্টরি);

  • getRoot() : "root" ডিরেক্টরি রিটার্ন করে, অর্থাৎ ডিরেক্টরি গাছের শীর্ষে থাকা ডিরেক্টরি;

  • startsWith() , endsWith() : পাথটি পাস করা পাথ দিয়ে শুরু/শেষ হয় কিনা তা পরীক্ষা করুন:

    
    import java.nio.file.Path;
    import java.nio.file.Paths;
    
    public class Main {
    
       public static void main(String[] args) {
    
           Path testFilePath = Paths.get("C:\\Users\\Username\\Desktop\\testFile.txt");
    
           Path fileName = testFilePath.getFileName();
           System.out.println(fileName);
    
           Path parent = testFilePath.getParent();
           System.out.println(parent);
    
           Path root = testFilePath.getRoot();
           System.out.println(root);
    
           boolean endWithTxt = testFilePath.endsWith("Desktop\\testFile.txt");
           System.out.println(endWithTxt);
    
           boolean startsWithLalala = testFilePath.startsWith("lalalala");
           System.out.println(startsWithLalala);
       }
    }
    

    কনসোল আউটপুট:

    
    testFile.txt
    C:\Users\Username\Desktop
    C:\
    true
    false
    

    endsWith() পদ্ধতিটি কীভাবে কাজ করে সেদিকে মনোযোগ দিন । এটি পরীক্ষা করে যে বর্তমান পথটি পাস করা পথ দিয়ে শেষ হয়েছে কিনা । বিশেষ করে, এটি পাথের মধ্যে কিনা , পাস করা স্ট্রিংয়ে নয়

    এই দুটি কলের ফলাফল তুলনা করুন:

    
    import java.nio.file.Path;
    import java.nio.file.Paths;
    
    public class Main {
    
       public static void main(String[] args) {
    
           Path testFilePath = Paths.get("C:\\Users\\Username\\Desktop\\testFile.txt");
    
           System.out.println(testFilePath.endsWith("estFile.txt"));
           System.out.println(testFilePath.endsWith("Desktop\\testFile.txt"));
       }
    }
    

    কনসোল আউটপুট:

    
    false
    true
    

    endsWith () পদ্ধতিটি অবশ্যই একটি প্রকৃত পাথ পাস করতে হবে, শুধুমাত্র অক্ষরের একটি সেট নয়: অন্যথায়, ফলাফল সর্বদা মিথ্যা হবে, এমনকি যদি বর্তমান পথটি সত্যিই অক্ষরের সেই ক্রম দিয়ে শেষ হয় (যেমনটি "estFile.txt" এর ক্ষেত্রে হয় "উপরের উদাহরণে)।

    উপরন্তু, পাথের পদ্ধতির একটি গোষ্ঠী রয়েছে যা পরম (পূর্ণ) এবং আপেক্ষিক পাথগুলির সাথে কাজ করা সহজ করে

আসুন এই পদ্ধতিগুলি দেখুন:
  • বুলিয়ান isAbsolute() সত্য ফেরত দেয় যদি বর্তমান পথটি পরম হয়:

    
    import java.nio.file.Path;
    import java.nio.file.Paths;
    
    public class Main {
    
       public static void main(String[] args) {
    
           Path testFilePath = Paths.get("C:\\Users\\Username\\Desktop\\testFile.txt");
    
           System.out.println(testFilePath.isAbsolute());
       }
    }
    

    কনসোল আউটপুট:

    
    true
    
  • Path normalize() : বর্তমান পাথকে "স্বাভাবিক" করে, এটি থেকে অপ্রয়োজনীয় উপাদানগুলি সরিয়ে দেয়। আপনি হয়তো জানেন যে জনপ্রিয় অপারেটিং সিস্টেমে চিহ্নগুলি "।" (বর্তমান ডিরেক্টরি) এবং ".." (প্যারেন্ট ডিরেক্টরি) প্রায়ই পাথ নির্ধারণ করতে ব্যবহৃত হয়। উদাহরণস্বরূপ, " ./Pictures/dog.jpg " এর অর্থ হল বর্তমান ডিরেক্টরিটিতে একটি "Pictures" ফোল্ডার রয়েছে, যার ফলে একটি "dog.jpg" ফাইল রয়েছে।

    এখানে দেখুন. যদি একটি পাথ ব্যবহার করে "।" অথবা ".." আপনার প্রোগ্রামে প্রদর্শিত হবে, normalize() পদ্ধতি তাদের সরিয়ে দেবে এবং একটি পাথ তৈরি করবে যাতে সেগুলি থাকে না:

    
    import java.nio.file.Path;
    import java.nio.file.Paths;
    
    public class Main {
    
       public static void main(String[] args) {
    
          
           Path path5 = Paths.get("C:\\Users\\Java\\.\\examples");
          
           System.out.println(path5.normalize());
          
           Path path6 = Paths.get("C:\\Users\\Java\\..\\examples");
           System.out.println(path6.normalize());
       }
    }
    

    কনসোল আউটপুট:

    
    C:\Users\Java\examples
    C:\Users\examples
    
  • পাথ আপেক্ষিক() : বর্তমান এবং পাস করা পথের মধ্যে আপেক্ষিক পথ গণনা করে।

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

    
    import java.nio.file.Path;
    import java.nio.file.Paths;
    
    public class Main {
    
       public static void main(String[] args) {
    
           Path testFilePath1 = Paths.get("C:\\Users\\Users\\Users\\Users");
           Path testFilePath2 = Paths.get("C:\\Users\\Users\\Users\\Users\\Username\\Desktop\\testFile.txt");
    
           System.out.println(testFilePath1.relativize(testFilePath2));
       }
    }
    

    কনসোল আউটপুট:

    
    Username\Desktop\testFile.txt
    

পথ পদ্ধতির সম্পূর্ণ তালিকা বেশ দীর্ঘ। আপনি ওরাকল ডকুমেন্টেশনে তাদের সব খুঁজে পেতে পারেন । এখন আমরা ফাইলগুলি বিবেচনা করতে এগিয়ে যাব ।

নথি পত্র

ফাইল হল একটি ইউটিলিটি ক্লাস যা ফাইল ক্লাসথেকে নেওয়া স্ট্যাটিক পদ্ধতিগুলিকে ধারণ করেফাইলগুলি অ্যারে বা সংগ্রহের সাথে তুলনীয়। পার্থক্য হল এটি ফাইলের সাথে কাজ করে, অ্যারে বা সংগ্রহ নয় :) এটি ফাইল এবং ডিরেক্টরি পরিচালনার উপর ফোকাস করে। ফাইল ক্লাসের স্ট্যাটিক পদ্ধতি ব্যবহার করে, আমরা ফাইল এবং ডিরেক্টরি তৈরি করতে, মুছতে এবং সরাতে পারি। এই অপারেশনগুলি createFile() (ডিরেক্টরির জন্য, createDirectory() ), move() , এবং delete() পদ্ধতিব্যবহার করে করা হয়সেগুলি কীভাবে ব্যবহার করবেন তা এখানে:

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;

public class Main {

   public static void main(String[] args) throws IOException {

       // Create a file
       Path testFile1 = Files.createFile(Paths.get("C:\\Users\\Username\\Desktop\\testFile111.txt"));
       System.out.println("Was the file created successfully?");
       System.out.println(Files.exists(Paths.get("C:\\Users\\Username\\Desktop\\testFile111.txt")));

       // Create a directory
       Path testDirectory = Files.createDirectory(Paths.get("C:\\Users\\Username\\Desktop\\testDirectory"));
       System.out.println("Was the directory created successfully?");
       System.out.println(Files.exists(Paths.get("C:\\Users\\Username\\Desktop\\testDirectory")));

       // Move the file from the desktop to the testDirectory directory. When you move a folder, you need to indicate its name in the folder!
       testFile1 = Files.move(testFile1, Paths.get("C:\\Users\\Username\\Desktop\\testDirectory\\testFile111.txt"), REPLACE_EXISTING);

       System.out.println("Did our file remain on the desktop?");
       System.out.println(Files.exists(Paths.get("C:\\Users\\Username\\Desktop\\testFile111.txt")));

       System.out.println("Has our file been moved to testDirectory?");
       System.out.println(Files.exists(Paths.get("C:\\Users\\Username\\Desktop\\testDirectory\\testFile111.txt")));

       // Delete a file
       Files.delete(testFile1);
       System.out.println("Does the file still exist?");
       System.out.println(Files.exists(Paths.get("C:\\Users\\Username\\Desktop\\testDirectory\\testFile111.txt")));
   }
}
এখানে আমরা প্রথমে ডেস্কটপে একটি ফাইল ( Files.createFile() পদ্ধতি) তৈরি করি। তারপরে আমরা একই অবস্থানে একটি ফোল্ডার তৈরি করি ( Files.createDirectory() পদ্ধতি)। এর পরে, আমরা ফাইলটি ( Files.move() পদ্ধতি) ডেস্কটপ থেকে এই নতুন ফোল্ডারে সরিয়ে ফেলি এবং অবশেষে আমরা ফাইলটি ( Files.delete() পদ্ধতি) মুছে ফেলি। কনসোল আউটপুট:

Was the file created successfully? 
true 
Was the directory created successfully? 
true
Did our file remain on the desktop? 
false 
Has our file been moved to testDirectory? 
true 
Does the file still exist? 
false
বিঃদ্রঃ:ইন্টারফেসের পদ্ধতির মতো Path, ক্লাসের অনেক পদ্ধতি FilesএকটিPath বস্তুকে ফেরত দেয়। ক্লাসের বেশিরভাগ পদ্ধতিও অবজেক্টকে ইনপুট হিসাবে Filesনেয় । Pathএখানে Paths.get()পদ্ধতিটি আপনার বিশ্বস্ত সহকারী হবে - এটির ভাল ব্যবহার করুন। আর কি আকর্ষণীয় Files? পুরানো Fileক্লাসের আসলেই কি অভাব ছিল একটা copy()পদ্ধতি! আমরা এই পাঠের শুরুতে এটি সম্পর্কে কথা বলেছি। এখন এটা দেখা করার সময়!

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;

public class Main {

   public static void main(String[] args) throws IOException {

       // Create a file
       Path testFile1 = Files.createFile(Paths.get("C:\\Users\\Username\\Desktop\\testFile111.txt"));
       System.out.println("Was the file created successfully?");
       System.out.println(Files.exists(Paths.get("C:\\Users\\Username\\Desktop\\testFile111.txt")));

       // Create a directory
       Path testDirectory2 = Files.createDirectory(Paths.get("C:\\Users\\Username\\Desktop\\testDirectory2"));
       System.out.println("Was the directory created successfully?");
       System.out.println(Files.exists(Paths.get("C:\\Users\\Username\\Desktop\\testDirectory2")));

       // Copy the file from the desktop to the testDirectory2 directory.
       testFile1 = Files.copy(testFile1, Paths.get("C:\\Users\\Username\\Desktop\\testDirectory2\\testFile111.txt"), REPLACE_EXISTING);

       System.out.println("Did our file remain on the desktop?");
       System.out.println(Files.exists(Paths.get("C:\\Users\\Username\\Desktop\\testFile111.txt")));

       System.out.println("Was our file copied to testDirectory?");
       System.out.println(Files.exists(Paths.get("C:\\Users\\Username\\Desktop\\testDirectory2\\testFile111.txt")));
   }
}
কনসোল আউটপুট:

Was the file created successfully? 
true 
Was the directory created successfully? 
true 
Did our file remain on the desktop? 
true 
Was our file copied to testDirectory? 
true
এখন আপনি প্রোগ্রামগতভাবে ফাইল কপি কিভাবে জানেন! :) অবশ্যই, Filesক্লাস আপনাকে শুধুমাত্র একটি ফাইল নিজেই পরিচালনা করতে দেয় না, তবে এর বিষয়বস্তু নিয়েও কাজ করতে দেয়। এটিতে write()একটি ফাইলে ডেটা লেখার পদ্ধতি এবং ডেটা পড়ার জন্য 3টি পদ্ধতি রয়েছে: read(), readAllBytes(), এবং readAllLines() আমরা শেষটি সম্পর্কে বিস্তারিতভাবে আলোচনা করব। কেন যে এক? কারণ এটি একটি খুব আকর্ষণীয় রিটার্ন টাইপ আছে: List<String>! অর্থাৎ, এটি আমাদের ফাইলের সমস্ত লাইনের একটি তালিকা প্রদান করে। forঅবশ্যই, এটি ফাইলের বিষয়বস্তুগুলির সাথে কাজ করা খুব সুবিধাজনক করে তোলে, কারণ সম্পূর্ণ ফাইল, লাইন দ্বারা লাইন, উদাহরণস্বরূপ, একটি সাধারণ লুপ ব্যবহার করে কনসোলে প্রদর্শিত হতে পারে:

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.List;

import static java.nio.charset.StandardCharsets.UTF_8;

public class Main {

   public static void main(String[] args) throws IOException {

       List<String> lines = Files.readAllLines(Paths.get("C:\\Users\\Username\\Desktop\\pushkin.txt"), UTF_8);

       for (String s: lines) {
           System.out.println(s);
       }
   }
}
কনসোল আউটপুট:

I still recall the wondrous moment: 
When you appeared before my sight, 
As though a brief and fleeting omen, 
Pure phantom in enchanting light.
সুপার সুবিধাজনক! :) এই ক্ষমতা জাভা 7-এ উপস্থিত হয়েছিল৷ স্ট্রিম API জাভা 8-এ উপস্থিত হয়েছিল৷ এটি জাভাতে কার্যকরী প্রোগ্রামিংয়ের কিছু উপাদান যুক্ত করে৷ সমৃদ্ধ ফাইল পরিচালনার ক্ষমতা সহ। কল্পনা করুন যে আমাদের নিম্নলিখিত কাজ রয়েছে: "যেমন" শব্দ দিয়ে শুরু হওয়া সমস্ত লাইনগুলি খুঁজুন, সেগুলিকে UPPERCASE এ রূপান্তর করুন এবং কনসোলে প্রদর্শন করুন৷ Filesজাভা 7 এ ক্লাস ব্যবহার করে একটি সমাধান কেমন হবে ? এটার মতো কিছু:

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;

import static java.nio.charset.StandardCharsets.UTF_8;

public class Main {

   public static void main(String[] args) throws IOException {

       List<String> lines = Files.readAllLines(Paths.get("C:\\Users\\Username\\Desktop\\pushkin.txt"), UTF_8);

       List<String> result = new ArrayList<>();

       for (String s: lines) {
           if (s.startsWith("As")) {
               String upper = s.toUpperCase();
               result.add(upper);
           }
       }

       for (String s: result) {
           System.out.println(s);
       }
   }
}
কনসোল আউটপুট:

AS THOUGH A BRIEF AND FLEETING OMEN, 
PURE PHANTOM IN ENCHANTING LIGHT.
মিশন সম্পন্ন হয়েছে, কিন্তু আপনি কি মনে করেন না যে এইরকম একটি সহজ কাজের জন্য আমাদের কোডটি একটু... ভার্বোস হয়ে উঠেছে? জাভা 8 এর স্ট্রিম API ব্যবহার করে, সমাধানটি আরও মার্জিত দেখায়:

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class Main {

   public static void main(String[] args) throws IOException {

       Stream<String> stream = Files.lines(Paths.get("C:\\Users\\Username\\Desktop\\pushkin.txt"));

       List<String> result  = stream
               .filter(line -> line.startsWith("As"))
               .map(String::toUpperCase)
               .collect(Collectors.toList());
       result.forEach(System.out::println);
   }
}
আমরা একই ফলাফল অর্জন করেছি, কিন্তু অনেক কম কোড সহ! আরও কী, কেউ বলতে পারবে না যে আমরা "পঠনযোগ্যতা" হারিয়ে ফেলেছি। আমি মনে করি আপনি সহজেই স্ট্রিম API এর সাথে পরিচিত না হয়েও এই কোডটি কী করে সে সম্পর্কে মন্তব্য করতে পারেন। সংক্ষেপে, একটি স্ট্রিম হল উপাদানগুলির একটি ক্রম, যার উপর আপনি বিভিন্ন ক্রিয়াকলাপ সম্পাদন করতে পারেন। আমরা পদ্ধতি থেকে একটি স্ট্রিম অবজেক্ট পাই Files.lines()এবং তারপরে এটিতে 3টি ফাংশন প্রয়োগ করি:
  1. আমরা filter()"As" দিয়ে শুরু হওয়া ফাইল থেকে শুধুমাত্র সেই লাইনগুলি নির্বাচন করতে পদ্ধতিটি ব্যবহার করি।

  2. আমরা map()পদ্ধতিটি ব্যবহার করে সমস্ত নির্বাচিত লাইনের মধ্য দিয়ে হেঁটে যাই এবং তাদের প্রতিটিকে UPPERCASE এ রূপান্তর করি।

  3. আমরা collect()প্রাপ্ত সমস্ত লাইনকে একটিতে একত্রিত করতে পদ্ধতিটি ব্যবহার করি List

আমরা একই আউটপুট পাই:

AS THOUGH A BRIEF AND FLEETING OMEN, 
PURE PHANTOM IN ENCHANTING LIGHT.
এখন আসুন আমাদের রুটি এবং মাখন, অর্থাৎ ফাইলগুলিতে ফিরে আসা যাক :) আজ আমরা যে শেষ ক্ষমতাটি বিবেচনা করব তা হল একটি ফাইল গাছের মধ্য দিয়ে হাঁটা । আধুনিক অপারেটিং সিস্টেমে, ফাইলের কাঠামো প্রায়শই একটি গাছের মতো দেখায়: এটির একটি মূল রয়েছে এবং শাখা রয়েছে, যার অন্যান্য শাখা থাকতে পারে ইত্যাদি। মূল এবং শাখাগুলি হল ডিরেক্টরি। উদাহরণস্বরূপ, ডিরেক্টরি " С:// " রুট হতে পারে। এটিতে দুটি শাখা রয়েছে: " C://Downloads " এবং " C://Users "। এই শাখাগুলির প্রতিটির দুটি শাখা রয়েছে: " C://Downloads/Pictures ", " C://Downloads/Video ", " C://Users/JohnSmith ", " C://Users/Pudge2005"। এবং এই শাখাগুলির পালাক্রমে অন্যান্য শাখা রয়েছে, ইত্যাদি এবং এই কারণেই আমরা এটিকে একটি গাছ বলি। লিনাক্সে, গঠনটি একই রকম, কিন্তু / ডিরেক্টরিটি হল রুট। এখন কল্পনা ফাইল, পাথ - 2করুন যে আমাদের রুট ডিরেক্টরি থেকে শুরু করতে হবে। , এর সমস্ত ফোল্ডার এবং সাবফোল্ডারগুলির মধ্যে দিয়ে যান, এবং কিছু নির্দিষ্ট বিষয়বস্তু আছে এমন ফাইলগুলি খুঁজে বের করুন৷ আমরা সেই ফাইলগুলির জন্য অনুসন্ধান করব যেখানে লাইনটি রয়েছে "এটি আমাদের প্রয়োজনীয় ফাইল!" আমরা "টেস্টফোল্ডার" ফোল্ডারটি নেব, যা চালু আছে ডেস্কটপ, রুট ডিরেক্টরি হিসাবে। এখানে এর বিষয়বস্তু রয়েছে: ফাইল, পথ - 3লেভেল1-এ এবং লেভেল1-বি ফোল্ডারগুলিতেও ফোল্ডার রয়েছে: ফাইল, পাথ - 4ফাইল, পাথ - 5এই "দ্বিতীয় স্তরের ফোল্ডারগুলিতে কোনও ফোল্ডার নেই, শুধুমাত্র পৃথক ফাইলগুলি: ফাইল, পাথ - 6ফাইল, পাথ - 7আমাদের প্রয়োজনীয় বিষয়বস্তু সহ 3টি ফাইলের ইচ্ছাকৃতভাবে ব্যাখ্যামূলক নাম দেওয়া হয়েছে: FileWeNeed1.txt, FileWeNeed2.txt, FileWeNeed3.txt। জাভা ব্যবহার করে এই ফাইলগুলি আমাদের খুঁজে বের করতে হবে। আমরা এটা কিভাবে করব? একটি ফাইল ট্রি অতিক্রম করার জন্য একটি খুব শক্তিশালী পদ্ধতি আমাদের সাহায্যে আসে Files.walkFileTree (): এখানে আমাদের কি করতে হবে। প্রথমত, আমাদের একটি প্রয়োজন FileVisitorFileVisitorএকটি বিশেষ ইন্টারফেস, যেখানে ফাইল ট্রি অতিক্রম করার পদ্ধতি বর্ণনা করা হয়েছে। বিশেষ করে, সেখানেই আমরা একটি ফাইলের বিষয়বস্তু পড়ার এবং আমাদের প্রয়োজনীয় পাঠ্য রয়েছে কিনা তা পরীক্ষা করার জন্য যুক্তি রাখব। FileVisitorআমাদের দেখতে কেমন তা এখানে :

import java.io.IOException;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.List;

public class MyFileVisitor extends SimpleFileVisitor<Path> {

   @Override
   public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {

       List<String> lines = Files.readAllLines(file);
       for (String s: lines) {
           if (s.contains("This is the file we need")) {
               System.out.println("We found a file we need!");
               System.out.println(file.toAbsolutePath());
               break;
           }
       }

       return FileVisitResult.CONTINUE;
   }
}
এই ক্ষেত্রে, আমাদের ক্লাস উত্তরাধিকারসূত্রে পাওয়া যায় SimpleFileVisitor। এটি এমন একটি শ্রেণী যা প্রয়োগ করে FileVisitor, যেখানে আমাদের শুধুমাত্র একটি পদ্ধতিকে ওভাররাইড করতে হবে: visitFile(). প্রতিটি ডিরেক্টরির প্রতিটি ফাইলের সাথে কী করা দরকার তা এখানে আমরা সংজ্ঞায়িত করি। ফাইলের কাঠামো অতিক্রম করার জন্য আপনার যদি আরও জটিল যুক্তির প্রয়োজন হয়, তাহলে আপনার নিজের বাস্তবায়ন লিখতে হবে FileVisitor। আপনাকে সেই ক্লাসে আরও 3টি পদ্ধতি প্রয়োগ করতে হবে:
  • preVisitDirectory(): একটি ফোল্ডারে প্রবেশ করার আগে কার্যকর করার যুক্তি;

  • visitFileFailed(): কোনো ফাইল পরিদর্শন করা না গেলে কার্যকর করার যুক্তি (অ্যাক্সেস নেই, বা অন্যান্য কারণে);

  • postVisitDirectory(): একটি ফোল্ডারে প্রবেশ করার পরে কার্যকর করার যুক্তি।

আমাদের এমন কোনো যুক্তির প্রয়োজন নেই, তাই আমরা ভালো আছি SimpleFileVisitor। পদ্ধতির ভিতরের যুক্তিটি visitFile()বেশ সহজ: ফাইলের সমস্ত লাইন পড়ুন, সেগুলিতে আমাদের প্রয়োজনীয় সামগ্রী রয়েছে কিনা তা পরীক্ষা করুন এবং যদি তাই হয় তবে কনসোলে পরম পথটি মুদ্রণ করুন। একমাত্র লাইন যা আপনাকে অসুবিধার কারণ হতে পারে তা হল:

return FileVisitResult.CONTINUE;
আসলে, এই খুব সহজ. এখানে আমরা সহজভাবে বর্ণনা করছি যে ফাইলটি পরিদর্শন করার পরে এবং সমস্ত প্রয়োজনীয় ক্রিয়াকলাপ সম্পাদিত হওয়ার পরে প্রোগ্রামটির কী করা উচিত। আমাদের ক্ষেত্রে, আমরা গাছটি অতিক্রম করতে চাই, তাই আমরা CONTINUEবিকল্পটি বেছে নিই। কিন্তু, বিকল্পভাবে, আমাদের একটি ভিন্ন উদ্দেশ্য থাকতে পারে: "এই যে ফাইলটি আমাদের প্রয়োজন" ধারণ করে এমন সমস্ত ফাইল খোঁজার পরিবর্তে, শুধুমাত্র একটি ফাইল খুঁজুন । এর পরে, প্রোগ্রামটি বন্ধ করা উচিত। এই ক্ষেত্রে, আমাদের কোড ঠিক একই রকম দেখাবে, কিন্তু বিরতির পরিবর্তে সেখানে থাকবে:

return FileVisitResult.TERMINATE;
ওয়েল, আসুন আমাদের কোড চালান এবং দেখুন এটি কাজ করে কিনা।

import java.io.IOException;
import java.nio.file.*;

public class Main {

   public static void main(String[] args) throws IOException {

       Files.walkFileTree(Paths.get("C:\\Users\\Username\\Desktop\\testFolder"), new MyFileVisitor());
   }
}
কনসোল আউটপুট:

We found a file we need! 
C:\Users\Username\Desktop\testFolder\FileWeNeed1.txt 
We found a file we need! 
C:\Users\Username\Desktop\testFolder\level1-a\level2-a-a\FileWeNeed2.txt 
We found a file we need! 
C:\Users\Username\Desktop\testFolder\level1-b\level2-b-b\FileWeNeed3.txt
চমৎকার! এটা কাজ করেছে! :) আপনি এই ছোট চ্যালেঞ্জটিও গ্রহণ করতে পারেন: SimpleFileVisitorএকটি সাধারণ দিয়ে প্রতিস্থাপন করুন FileVisitor, সমস্ত 4টি পদ্ধতিকে ওভাররাইড করুন এবং প্রোগ্রামটির জন্য আপনার নিজস্ব উদ্দেশ্য নিয়ে আসুন। উদাহরণস্বরূপ, আপনি একটি প্রোগ্রাম লিখতে পারেন যা তার সমস্ত ক্রিয়াগুলি লগ করে: ফাইল বা ফোল্ডারের নামটি প্রবেশ করার আগে বা পরে প্রদর্শন করুন। এখন এ পর্যন্তই. শীঘ্রই আবার দেখা হবে! :)
মন্তব্য
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION