हाय! आज आपण फाइल्स आणि डिरेक्टरीसह काम करण्याबद्दल बोलू. फाइल सामग्री कशी व्यवस्थापित करायची हे तुम्हाला आधीच माहित आहे: आम्ही यासाठी बरेच धडे समर्पित केले आहेत :) मला वाटते की या हेतूंसाठी वापरलेले काही वर्ग लक्षात ठेवणे तुम्हाला सोपे वाटते. आजच्या धड्यात, आम्ही विशेषत: फाइल व्यवस्थापनाबद्दल बोलू: तयार करणे, नाव बदलणे इ. जावा 7 पूर्वी, अशा सर्व ऑपरेशन्स फाइल क्लास वापरून केल्या जात होत्या. आपण याबद्दल येथे वाचू शकता . पण Java 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() : "रूट" डिरेक्टरी, म्हणजे डिरेक्टरी ट्रीच्या शीर्षस्थानी असलेली निर्देशिका;

  • 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
    
  • पाथ नॉर्मलाइज() : सध्याचा मार्ग "सामान्यीकृत करतो", त्यातून अनावश्यक घटक काढून टाकतो. तुम्हाला माहित असेल की लोकप्रिय ऑपरेटिंग सिस्टममध्ये "" ही चिन्हे आहेत. (वर्तमान निर्देशिका) आणि ".." (पॅरेंट डिरेक्टरी) सहसा पथ नियुक्त करण्यासाठी वापरल्या जातात. उदाहरणार्थ, " ./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
    

पथ पद्धतींची संपूर्ण यादी बरीच मोठी आहे. तुम्ही ते सर्व Oracle दस्तऐवजीकरणात शोधू शकता . आता आपण Files वर विचार करू .

फाईल्स

फाइल्स हा एक युटिलिटी क्लास आहे ज्यामध्ये फाइल क्लासमधून घेतलेल्या स्टॅटिक पद्धती असतात. फाइल्सची तुलना अॅरे किंवा कलेक्शनशी केली जाते. फरक असा आहे की ते फाइल्ससह कार्य करते, अॅरे किंवा संग्रह नाही :) ते फाइल्स आणि निर्देशिका व्यवस्थापित करण्यावर लक्ष केंद्रित करते. Files क्लासच्या स्टॅटिक पद्धतींचा वापर करून, आम्ही फाइल्स आणि डिरेक्टरी तयार करू, हटवू आणि हलवू शकतो. ही ऑपरेशन्स 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.
सुपर सोयीस्कर! :) ही क्षमता Java 7 मध्ये दिसून आली. स्ट्रीम API Java 8 मध्ये दिसली. हे Java मध्ये फंक्शनल प्रोग्रामिंगचे काही घटक जोडते. समृद्ध फाइल हाताळणी क्षमतांचा समावेश आहे. अशी कल्पना करा की आमच्याकडे खालील कार्य आहे: "अस" शब्दापासून सुरू होणाऱ्या सर्व ओळी शोधा, त्यांना UPPERCASE मध्ये रूपांतरित करा आणि कन्सोलवर प्रदर्शित करा. FilesJava 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.
मिशन पूर्ण झाले, पण एवढ्या साध्या कार्यासाठी आमचा कोड थोडा... शब्दश: झाला असे तुम्हाला वाटत नाही का? Java 8 च्या Stream 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);
   }
}
आम्ही समान परिणाम प्राप्त केला, परंतु खूपच कमी कोडसह! इतकेच काय, आम्ही "वाचनीयता" गमावली असे कोणी म्हणू शकत नाही. मला वाटते की स्ट्रीम एपीआयशी परिचित नसतानाही तुम्ही हा कोड काय करतो यावर सहज टिप्पणी करू शकता. थोडक्यात, प्रवाह हा घटकांचा एक क्रम आहे, ज्यावर तुम्ही विविध ऑपरेशन्स करू शकता. आम्हाला पद्धतीमधून स्ट्रीम ऑब्जेक्ट मिळतो Files.lines()आणि नंतर त्यावर 3 फंक्शन्स लागू करा:
  1. आम्ही filter()"As" ने सुरू होणाऱ्या फाईलमधून फक्त त्या ओळी निवडण्यासाठी पद्धत वापरतो.

  2. आम्ही पद्धत वापरून निवडलेल्या सर्व ओळींमधून फिरतो map()आणि त्या प्रत्येकाला UPPERCASE मध्ये रूपांतरित करतो.

  3. collect()प्राप्त झालेल्या सर्व रेषा a मध्ये एकत्रित करण्यासाठी आम्ही पद्धत वापरतो 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कल्पना करा की आपल्याला रूट डिरेक्टरीपासून प्रारंभ करणे आवश्यक आहे. , त्याच्या सर्व फोल्डर्स आणि सबफोल्डर्समधून चाला, आणि काही विशिष्ट सामग्री असलेल्या फायली शोधा. आम्ही "आम्हाला आवश्यक असलेली ही फाईल आहे!" ओळ असलेल्या फाइल्स शोधू आम्ही "testFolder" फोल्डर घेऊ, जे चालू आहे. डेस्कटॉप, रूट डिरेक्ट्री म्हणून. येथे त्याची सामग्री आहे: फाइल्स, पथ - 3स्तर1-ए आणि लेव्हल1-बी फोल्डर्समध्ये देखील फोल्डर्स असतात: फाइल्स, पथ - 4फाइल्स, पथ - 5या "सेकंड लेव्हल फोल्डर्स" मध्ये कोणतेही फोल्डर्स नाहीत, फक्त वैयक्तिक फाइल्स: फाइल्स, पथ - 6फाइल्स, पथ - 7आम्हाला आवश्यक असलेल्या सामग्रीसह 3 फाइल्सना जाणीवपूर्वक स्पष्टीकरणात्मक नावे दिली आहेत: FileWeNeed1.txt, FileWeNeed2.txt, FileWeNeed3.txt. या तंतोतंत फाईल्स आहेत ज्या आम्हाला Java वापरून शोधण्यासाठी आवश्यक आहेत. आम्ही हे कसे करू? फाईल ट्री ट्रॅव्हर्स करण्यासाठी एक अतिशय शक्तिशाली पद्धत आमच्या मदतीला येते: Files.walkFileTree (). आम्हाला काय करावे लागेल ते येथे आहे. प्रथम, आम्हाला एक आवश्यक आहे FileVisitor. FileVisitorएक विशेष इंटरफेस आहे, ज्यामध्ये फाईल ट्री ट्रॅव्हर्स करण्याच्या पद्धती वर्णन केल्या आहेत. विशेषतः, तिथेच आम्ही फाईलमधील मजकूर वाचण्यासाठी आणि त्यात आम्हाला आवश्यक असलेला मजकूर आहे की नाही हे तपासण्यासाठी तर्कशास्त्र ठेवू. आमचे कसे 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 पद्धती ओव्हरराइड करा आणि प्रोग्रामसाठी तुमच्या स्वतःच्या उद्देशाने या. उदाहरणार्थ, आपण एक प्रोग्राम लिहू शकता जो त्याच्या सर्व क्रिया लॉग करतो: फाइल किंवा फोल्डरचे नाव प्रविष्ट करण्यापूर्वी किंवा नंतर प्रदर्शित करा. सध्या एवढेच. लवकरच भेटू! :)