CodeGym /Java Blog /अनियमित /जावा फ़ाइलें, पथ
John Squirrels
स्तर 41
San Francisco

जावा फ़ाइलें, पथ

अनियमित ग्रुप में प्रकाशित
नमस्ते! आज हम फाइलों और निर्देशिकाओं के साथ काम करने के बारे में बात करेंगे। आप पहले से ही जानते हैं कि फ़ाइल सामग्री का प्रबंधन कैसे किया जाता है: हमने इसके लिए बहुत सारे पाठ समर्पित किए हैं :) मुझे लगता है कि आपको इन उद्देश्यों के लिए उपयोग की जाने वाली कुछ कक्षाओं को याद रखना आसान लगता है। आज के पाठ में, हम विशेष रूप से फ़ाइल प्रबंधन के बारे में बात करेंगे: बनाना, नाम बदलना आदि। Java 7 से पहले, ऐसे सभी ऑपरेशन फ़ाइल क्लास का उपयोग करके किए जाते थे। आप इसके बारे में यहाँ पढ़ सकते हैं । लेकिन जावा 7 में, भाषा के रचनाकारों ने यह बदलने का फैसला किया कि हम फाइलों और निर्देशिकाओं के साथ कैसे काम करते हैं। ऐसा इसलिए हुआ क्योंकि फाइल क्लास में कई कमियां थीं। उदाहरण के लिए, इसमें कॉपी () विधि नहीं थी , जो आपको एक फ़ाइल को एक स्थान से दूसरे स्थान पर कॉपी करने देती थी (एक आवश्यक क्षमता)। इसके साथ मेंफ़ाइल वर्ग में कुछ विधियाँ थीं जो बूलियन मान लौटाती थीं। जब कोई त्रुटि होती है, तो ऐसी विधि झूठी होती है। यह एक अपवाद नहीं फेंकता है, जिससे त्रुटियों की पहचान करना और उनके कारणों का निदान करना बहुत मुश्किल हो जाता है। एकल फ़ाइल वर्ग के स्थान पर, 3 वर्ग प्रकट हुए: पथ , पथ और फ़ाइलें । ठीक है, सटीक होने के लिए, पथ एक इंटरफ़ेस है, कक्षा नहीं। आइए जानें कि वे एक दूसरे से कैसे भिन्न हैं और हमें उनमें से प्रत्येक की आवश्यकता क्यों है। आइए सबसे सरल से शुरू करें: पथ

के रास्ते

पथ एक स्थिर विधि के साथ एक बहुत ही सरल वर्ग है: get() । यह पूरी तरह से पारित स्ट्रिंग या यूआरआई से पथ वस्तु प्राप्त करने के लिए बनाया गया था। इसकी कोई अन्य कार्यक्षमता नहीं है। यहाँ काम पर इसका एक उदाहरण है:

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 () : "रूट" निर्देशिका लौटाता है, अर्थात निर्देशिका ट्री के शीर्ष पर स्थित निर्देशिका;

  • startWith() , endWith() : जांचें कि क्या पथ पारित पथ के साथ शुरू/समाप्त होता है:

    
    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
    

    इस बात पर ध्यान दें कि एंड्सविथ () विधि कैसे काम करती है। यह जाँचता है कि क्या वर्तमान पथ पारित पथ के साथ समाप्त होता है । विशेष रूप से, क्या यह पथ में है , पारित स्ट्रिंग में नहीं

    इन दो कॉल के परिणामों की तुलना करें:

    
    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
    

    एंड्सविथ () विधि को एक वास्तविक पथ पारित किया जाना चाहिए, न कि केवल वर्णों का एक सेट: अन्यथा, परिणाम हमेशा गलत होगा, भले ही वर्तमान पथ वास्तव में वर्णों के उस क्रम के साथ समाप्त हो (जैसा कि "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 " का अर्थ है कि वर्तमान निर्देशिका में "पिक्चर्स" फ़ोल्डर है, जिसमें बदले में "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 पर विचार करने के लिए आगे बढ़ेंगे ।

फ़ाइलें

फ़ाइलें एक उपयोगिता वर्ग है जो फ़ाइल वर्गसे निकाले गए स्थिर तरीकों को रखती हैफ़ाइलें Arrays या Collections से तुलनीय हैं। अंतर यह है कि यह फाइलों के साथ काम करता है, सरणियों या संग्रहों के साथ नहीं :) यह फाइलों और निर्देशिकाओं के प्रबंधन पर केंद्रित है। फ़ाइलें वर्ग के स्थिर तरीकों का उपयोग करके, हम फ़ाइलों और निर्देशिकाओं को बना, हटा और स्थानांतरित कर सकते हैं। ये ऑपरेशन createFile () (निर्देशिकाओं के लिए, createDirectory () ), मूव () और डिलीट () विधियों का उपयोग करके किए जाते हैं। यहां उनका उपयोग करने का तरीका बताया गया है:

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 में दिखाई दी। स्ट्रीम एपीआई जावा 8 में दिखाई दी। यह जावा में कार्यात्मक प्रोग्रामिंग के कुछ तत्व जोड़ता है। समृद्ध फ़ाइल हैंडलिंग क्षमताओं सहित। कल्पना करें कि हमारे पास निम्नलिखित कार्य हैं: "As" शब्द से शुरू होने वाली सभी पंक्तियों को खोजें, उन्हें अपरकेस में बदलें, और उन्हें कंसोल पर प्रदर्शित करें। 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 के स्ट्रीम एपीआई का उपयोग करते हुए, समाधान अधिक सुरुचिपूर्ण दिखता है:

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()और उनमें से प्रत्येक को अपरकेस में परिवर्तित करते हैं।

  3. हम collect()सभी प्राप्त लाइनों को एक में इकट्ठा करने के लिए विधि का उपयोग करते हैं List

हमें वही आउटपुट मिलता है:

AS THOUGH A BRIEF AND FLEETING OMEN, 
PURE PHANTOM IN ENCHANTING LIGHT.
अब हम अपनी रोटी और मक्खन, यानी फाइलों पर लौटते हैं :) आखिरी क्षमता जिस पर हम आज विचार करेंगे, वह फाइल ट्री के माध्यम से चल रही है । आधुनिक ऑपरेटिंग सिस्टम में, फ़ाइल संरचना अक्सर एक पेड़ की तरह दिखती है: इसकी एक जड़ होती है और वहाँ शाखाएँ होती हैं, जिनकी अन्य शाखाएँ हो सकती हैं, आदि। जड़ और शाखाएँ निर्देशिकाएँ हैं। उदाहरण के लिए, निर्देशिका " सी: // " रूट हो सकती है। इसमें दो शाखाएं शामिल हैं: " सी: // डाउनलोड " और " सी: // उपयोगकर्ता "। इनमें से प्रत्येक शाखा की दो शाखाएँ हैं: " C://डाउनलोड/पिक्चर्स ", " C://डाउनलोड/वीडियो ", " C://उपयोगकर्ता/जॉनस्मिथ ", " C://उपयोगकर्ता/Pudge2005"। और इन शाखाओं की बारी-बारी से अन्य शाखाएँ आदि होती हैं और इसीलिए हम इसे एक पेड़ कहते हैं। लिनक्स पर, संरचना समान है, लेकिन / निर्देशिका जड़ है। अब कल्पना फ़ाइलें, पथ - 2करें कि हमें मूल निर्देशिका से शुरू करने की आवश्यकता है , इसके सभी फ़ोल्डरों और सबफ़ोल्डरों के माध्यम से चलें, और ऐसी फ़ाइलें खोजें जिनमें कुछ विशेष सामग्री हो। हम उन फ़ाइलों की खोज करेंगे जिनमें "यह वह फ़ाइल है जिसकी हमें आवश्यकता है!" हम "testFolder" फ़ोल्डर लेंगे, जो चालू है डेस्कटॉप, रूट डायरेक्टरी के रूप में। इसकी सामग्री यहां दी गई है: फ़ाइलें, पथ - 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