سلام! امروز در مورد کار با فایل ها و دایرکتوری ها صحبت خواهیم کرد. شما قبلاً می دانید که چگونه محتویات فایل ها را مدیریت کنید: ما کلاس های زیادی به این موضوع اختصاص داده بودیم :) من فکر می کنم می توانید به راحتی چندین کلاس را که برای این اهداف مورد نیاز هستند به خاطر بسپارید. در سخنرانی امروز ما به طور خاص در مورد مدیریت فایل - ایجاد، تغییر نام و غیره صحبت خواهیم کرد. قبل از جاوا 7، تمام این عملیات با استفاده از File. می توانید در مورد کارهای او اینجا بخوانید . اما در جاوا 7، سازندگان این زبان تصمیم گرفتند نحوه کار با فایل ها و دایرکتوری ها را تغییر دهند. این به دلیل این واقعیت بود که کلاس Fileدارای یک سری معایب بود. copy()به عنوان مثال، روشی که به شما امکان می دهد یک فایل را از یک مکان به مکان دیگر کپی کنید (یک ویژگی ظاهراً به وضوح مورد نیاز) نداشت . علاوه بر این، کلاس Fileمتدهای بسیار زیادی داشت که booleanمقادیر - را برمی‌گرداند. اگر خطایی رخ دهد، چنین روشی به جای ایجاد استثنا، false را برمی‌گرداند، که تشخیص خطاها و تعیین علل آنها را بسیار دشوار می‌کند. به جای یک کلاس، Fileبه اندازه 3 کلاس ظاهر شد Paths: Pathو Files. خوب، به طور دقیق، Pathاین یک رابط است، نه یک کلاس. بیایید بفهمیم که چگونه آنها با یکدیگر متفاوت هستند و چرا هر یک از آنها مورد نیاز است. بیایید با ساده ترین چیز شروع کنیم - Paths.

راه ها

Pathsیک کلاس بسیار ساده با یک روش استاتیک واحد است get(). این فقط برای به دست آوردن یک شی از نوع از رشته یا URI ایجاد شده است Path. هیچ کارکرد دیگری ندارد. در اینجا نمونه ای از کارهای او آورده شده است:
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، بیایید بفهمیم که چیست Pathو چرا به آن نیاز است :)

مسیر

Pathبه طور کلی، یک آنالوگ بازطراحی شده از File. کار کردن با آن بسیار ساده تر از با آن است File. در ابتدا ، بسیاری از متدهای کاربردی (استاتیک) از آن حذف و به کلاس منتقل شدند Files. ثانیاً ، Pathمقادیر برگشتی روش ها سفارش داده شد. در کلاس، Fileمتدها این String، آن boolean، آن را برگرداندند File- فهمیدن آن آسان نبود. برای مثال، روشی وجود داشت getParent()که مسیر والد فایل فعلی را به صورت رشته ای برمی گرداند. اما در همان زمان روشی وجود داشت getParentFile()که همان چیزی را برمی گرداند، اما به صورت یک شی File! این به وضوح زائد است. بنابراین، در رابط، Pathروش getParent()و روش های دیگر برای کار با فایل ها به سادگی یک شی را برمی گرداند Path. بدون انبوهی از گزینه ها - همه چیز آسان و ساده است. چه روش های مفیدی دارد Path؟ در اینجا به تعدادی از آنها و نمونه کارهای آنها اشاره می کنیم:
  • 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"));
       }
    }

    خروجی کنسول:

    غلط
    درست

    شما باید مسیر کامل را به متد منتقل کنید endsWith()، و نه فقط مجموعه ای از کاراکترها: در غیر این صورت، نتیجه همیشه نادرست خواهد بود ، حتی اگر مسیر فعلی واقعاً با چنین دنباله ای از کاراکترها پایان یابد (مانند مورد "estFile.txt" ” در مثال بالا).

    علاوه بر این، گروهی از روش ها وجود دارد که کار با مسیرهای مطلق (کامل) و نسبی را ساده می کندPath .

بیایید به این روش ها نگاه کنیم:
  • boolean isAbsolute()- اگر مسیر فعلی مطلق باشد، true را برمی‌گرداند:

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

    خروجی کنسول:

    درست است، واقعی

  • 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

  • Path relativize()- مسیر نسبی بین مسیر فعلی و عبوری را محاسبه می کند.

    مثلا:

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

    خروجی کنسول:

    نام کاربری\Desktop\testFile.txt

لیست کامل روش ها Pathبسیار بزرگ است. می توانید همه آنها را در اسناد Oracle بیابید . ما به بررسی خواهیم پرداخت Files.

فایل ها

Files- این یک کلاس کاربردی است که در آن متدهای استاتیک از کلاس منتقل شده اند File. Files- این تقریباً مشابه Arraysیا است Collections، فقط با فایل ها کار می کند، نه با آرایه ها و مجموعه ها :) روی مدیریت فایل ها و دایرکتوری ها متمرکز است. با استفاده از روش های استاتیک 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 {

       //file creation
       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 directory
       Path testDirectory = Files.createDirectory(Paths.get("C:\\Users\\Username\\Desktop\\testDirectory"));
       System.out.println("Was the directory successfully created?");
       System.out.println(Files.exists(Paths.get("C:\\Users\\Username\\Desktop\\testDirectory")));

       //move file from desktop to testDirectory. You need to move with the name of the file in the folder!
       testFile1 = Files.move(testFile1, Paths.get("C:\\Users\\Username\\Desktop\\testDirectory\\testFile111.txt"), REPLACE_EXISTING);

       System.out.println("Is our file left 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")));

       //remove 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()). پس از آن، فایل (method Files.move()) را از دسکتاپ به این پوشه جدید منتقل می کنیم و در پایان فایل (method Files.delete()) را حذف می کنیم. خروجی کنسول: آیا فایل با موفقیت ایجاد شد؟ درست است آیا دایرکتوری با موفقیت ایجاد شد؟ true آیا فایل ما هنوز روی دسکتاپ است؟ false آیا فایل ما به testDirectory منتقل شده است؟ true آیا فایل هنوز وجود دارد؟ نادرست توجه کنید:درست مانند متدهای واسط 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 {

       //file creation
       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 directory
       Path testDirectory2 = Files.createDirectory(Paths.get("C:\\Users\\Username\\Desktop\\testDirectory2"));
       System.out.println("Was the directory successfully created?");
       System.out.println(Files.exists(Paths.get("C:\\Users\\Username\\Desktop\\testDirectory2")));

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

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

       System.out.println("Has our file been copied to testDirectory?");
       System.out.println(Files.exists(Paths.get("C:\\Users\\Username\\Desktop\\testDirectory2\\testFile111.txt")));
   }
}
خروجی کنسول: آیا فایل با موفقیت ایجاد شد؟ درست است آیا دایرکتوری با موفقیت ایجاد شد؟ true آیا فایل ما هنوز روی دسکتاپ است؟ true آیا فایل ما در 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);
       }
   }
}
خروجی کنسول: من یک لحظه شگفت انگیز را به یاد می آورم: تو در برابر من ظاهر شدی، مانند دیدی زودگذر، مانند نابغه ای از زیبایی ناب. خیلی راحت! :) این ویژگی در جاوا 7 ظاهر شد. در جاوا 8، Stream API ظاهر شد که برخی از عناصر برنامه نویسی کاربردی را به جاوا اضافه کرد. از جمله قابلیت های غنی تر برای کار با فایل ها. تصور کنید که ما یک وظیفه داریم: تمام خطوط یک فایل که با کلمه "How" شروع می شود را پیدا کنید، آنها را به UPPER CASE تبدیل کنید و آنها را به کنسول خروجی دهید. راه حل با استفاده از کلاس 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("How")) {
               String upper = s.toUpperCase();
               result.add(upper);
           }
       }

       for (String s: result) {
           System.out.println(s);
       }
   }
}
خروجی کنسول: مانند یک چشم انداز روزه، مانند یک نابغه از زیبایی خالص. به نظر می رسد ما این کار را انجام داده ایم، اما آیا فکر نمی کنید که برای چنین کار ساده ای کد ما کمی ... پرمخاطب بود؟ با استفاده از 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("How"))
               .map(String::toUpperCase)
               .collect(Collectors.toList());
       result.forEach(System.out::println);
   }
}
ما به همین نتیجه رسیدیم، اما با کد بسیار کمتر! علاوه بر این، نمی توان گفت که ما در «خوانایی» گم شده ایم. فکر می‌کنم حتی اگر با Stream API آشنا نباشید، می‌توانید به راحتی درباره کاری که این کد انجام می‌دهد، نظر دهید. اما به طور خلاصه، استریم مجموعه ای از عناصر است که می توانید عملکردهای مختلفی را بر روی آن انجام دهید. شی Stream را از متد دریافت می کنیم Files.lines()و 3 تابع را به آن اعمال می کنیم:
  1. با استفاده از روش، filter()فقط خطوطی را از فایل انتخاب می کنیم که با "How" شروع می شوند.

  2. تمام خطوط انتخاب شده را با استفاده از روش مرور می کنیم map()و هر کدام را به UPPER CASE می آوریم.

  3. تمام خطوط به دست آمده را با هم ترکیب می کنیم تا Listاز collect().

در خروجی همان نتیجه را می گیریم: مانند یک چشم انداز روزه دار، مانند یک نابغه از زیبایی خالص. اگر علاقه مند به آشنایی بیشتر با قابلیت های این کتابخانه هستید، خواندن این مقاله را به شما توصیه می کنیم . ما به گوسفندمان یعنی پرونده ها برمی گردیم :) آخرین امکانی که امروز در نظر خواهیم گرفت قدم زدن در درخت پرونده است . ساختار فایل در سیستم عامل های مدرن اغلب به شکل یک درخت است: ریشه دارد و شاخه هایی وجود دارد که شاخه های دیگر را می توان از آنها جدا کرد و غیره. دایرکتوری ها نقش ریشه و شاخه را بازی می کنند. به عنوان مثال، دایرکتوری " C:// " می تواند به عنوان ریشه عمل کند . دو شاخه از آن منشعب می شود: " C://Downloads " و " C://Users ". از هر یک از این شعب 2 شعبه دیگر وجود دارد: " C://Downloads/Pictures "، " C://Downloads/Video "، " C://Users/JohnSmith "، " C://Users/Pudge2005 " . شاخه های دیگر از این شاخه ها و غیره منشعب می شوند. - اینطوری یک درخت معلوم می شود. در لینوکس تقریباً یکسان به نظر می رسد، فقط در آنجا دایرکتوری به عنوان ریشه عمل می کند / فایل ها، مسیر - 2 حالا تصور کنید که ما یک وظیفه داریم: با دانستن دایرکتوری ریشه، باید از آن عبور کنیم، پوشه های همه سطوح را بررسی کنیم و فایل هایی را با محتوا در آنها پیدا کنیم. نیاز داریم. ما به دنبال فایل های حاوی خط "این فایلی است که ما نیاز داریم!" دایرکتوری ریشه ما پوشه "testFolder" خواهد بود که روی دسکتاپ قرار دارد. داخل آن دارای محتویات زیر است: فایل ها، مسیر - 3در داخل پوشه‌های level1-a و level1-b نیز پوشه‌هایی وجود دارد: فایل ها، مسیر - 4فایل ها، مسیر - 5در داخل این "پوشه‌های سطح دوم" هیچ پوشه دیگری وجود ندارد، فقط فایل‌های فردی وجود دارد: فایل ها، مسیر - 6فایل ها، مسیر - 7ما به طور خاص 3 فایل را با محتوایی که داریم تعیین می‌کنیم. نیاز با نام‌های واضح - FileWeNeed1.txt، FileWeNeed2.txt، FileWeNeed3.txt اینها مواردی هستند که ما باید بر اساس محتوا با استفاده از جاوا پیدا کنیم. ما چطوری می تونیم این کار را انجام بدهیم؟ یک روش بسیار قدرتمند برای عبور از درخت فایل به کمک می آید - 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("Required file found!");
               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());
   }
}
خروجی کنسول: فایل مورد نیاز پیدا شد! C:\Users\Username\Desktop\testFolder\FileWeNeed1.txt فایل مورد نیاز پیدا شد! C:\Users\Username\Desktop\testFolder\level1-a\level2-aa\FileWeNeed2.txt فایل مورد نیاز پیدا شد! C:\Users\Username\Desktop\testFolder\level1-b\level2-bb\FileWeNeed3.txt عالی، ما این کار را کردیم! :) اگر می خواهید بیشتر بدانید ، این مقاله راwalkFileTree() به شما توصیه می کنم . شما همچنین می توانید یک کار کوچک را تکمیل کنید - آن را با یک کار معمولی جایگزین کنید ، هر 4 روش را اجرا کنید و هدفی را برای این برنامه در نظر بگیرید. برای مثال، می‌توانید برنامه‌ای بنویسید که تمام اقدامات شما را ثبت کند: نام یک فایل یا پوشه را قبل/بعد از وارد کردن آنها در کنسول نمایش دهید. همین - بعداً می بینمت! :) SimpleFileVisitorFileVisitor