JavaRush /Java Blogu /Random-AZ /Java faylları, yol

Java faylları, yol

Qrupda dərc edilmişdir
Salam! Bu gün biz fayl və qovluqlarla işləmək haqqında danışacağıq. Siz artıq faylların məzmununu necə idarə edəcəyinizi bilirsiniz: buna həsr olunmuş çoxlu dərslərimiz var idi :) Məncə, bu məqsədlər üçün lazım olan bir neçə sinfi asanlıqla xatırlaya bilərsiniz. Bugünkü mühazirəmizdə biz xüsusi olaraq faylların idarə edilməsindən danışacağıq - yaradılması, adının dəyişdirilməsi və s. Java 7-dən əvvəl bütün bu cür əməliyyatlar File. Onun işi haqqında burada oxuya bilərsiniz . Lakin Java 7-də dilin yaradıcıları fayl və qovluqlarla işləmə qaydalarını dəyişməyə qərar verdilər. FileBu, sinfin bir sıra çatışmazlıqlara malik olması ilə əlaqədar idi . copy()Məsələn, onun bir faylı bir yerdən digərinə köçürməyə imkan verən metodu yox idi (görünür, lazım olan xüsusiyyət). Bundan əlavə, sinifdə dəyərləri Fileqaytaran kifayət qədər çox üsul var idi boolean. Səhv baş verərsə, belə bir üsul istisna atmaq əvəzinə false qaytarır, bu da səhvlərin diaqnozunu və onların səbəblərini müəyyən etməyi çox çətinləşdirir. Tək bir sinif əvəzinə File3 sinif meydana çıxdı: Paths, PathFiles. Yaxşı, dəqiq desək, Pathbu sinif deyil, interfeysdir. Onların bir-birindən necə fərqləndiyini və hər birinə nə üçün lazım olduğunu anlayaq. Ən asan şeydən başlayaq - Paths.

Yollar

Pathstək statik metodu olan çox sadə sinifdir get(). O, yalnız ötürülən sətirdən və ya URI-dən tipli obyekt əldə etmək üçün yaradılmışdır Path. Başqa heç bir funksiyası yoxdur. Onun işindən bir nümunə:
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");
   }
}
Ən çətin sinif deyil, elə deyilmi? :) Yaxşı, tipli bir obyekt əldə etdiyimiz üçün onun nə olduğunu və nə üçün lazım olduğunu Pathanlayaq :)Path

Yol

Path, ümumiyyətlə, yenidən işlənmiş analoqudur File. Onunla işləmək onunla işləməkdən daha asandır File. Əvvəlcə bir çox faydalı (statik) metodlar ondan çıxarılaraq sinifə köçürüldü Files. İkincisi , Pathmetodların qaytarılma dəyərləri sifariş edildi. Sinifdə Fileüsullar bunu String, o boolean, bunu qaytarırdı File- bunu anlamaq asan deyildi. Məsələn, getParent()cari fayl üçün ana yolu sətir kimi qaytaran bir üsul var idi. Ancaq eyni zamanda getParentFile()eyni şeyi qaytaran bir üsul var idi, ancaq bir obyekt şəklində File! Bu açıq-aşkar lazımsızdır. Buna görə interfeysdə fayllarla işləmək üçün Pathmetod və digər üsullar sadəcə bir obyekt qaytarır . Seçimlər çox deyil - hər şey asan və sadədir. Onun hansı faydalı üsulları var ? Onlardan bəziləri və işlərindən nümunələr: getParent()PathPath
  • getFileName()— faylın adını yoldan qaytarır;

  • getParent()— cari yola (yəni kataloq ağacında daha yüksək olan kataloqa) münasibətdə “ana” kataloqunu qaytarır;

  • getRoot()— “kök” kataloqunu qaytarır; yəni kataloq ağacının yuxarı hissəsində olan;

  • startsWith(), endsWith()— yolun keçən yol ilə başladığını/bitdiyini yoxlayın:

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

    Konsol çıxışı:

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

    Metodun necə işlədiyinə diqqət yetirin endsWith(). Cari yolun keçən yol ilə bitib-bitirmədiyini yoxlayır . O , simvollar toplusunda deyil , yoldadır .

    Bu iki zəngin nəticələrini müqayisə edin:

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

    Konsol çıxışı:

    yalan
    doğru

    Metodun tam yolunu keçmək lazımdır endsWith(), sadəcə simvollar dəsti deyil: əks halda, cari yol həqiqətən belə simvol ardıcıllığı ilə bitsə belə, nəticə həmişə yalan olacaq ("estFile.txt" vəziyyətində olduğu kimi ” yuxarıdakı nümunədə).

    Bundan əlavə, mütləq (tam) və nisbi yollarla işləməyi asanlaşdıran bir qrup üsul varPath .

Bu üsullara nəzər salaq:
  • boolean isAbsolute()— cari yol mütləqdirsə, doğru qaytarır:

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

    Konsol çıxışı:

    doğru

  • Path normalize()— cari yolu “normallaşdırır”, ondan lazımsız elementləri çıxarır. Bilə bilərsiniz ki, məşhur əməliyyat sistemləri yolları ifadə edərkən tez-tez “.” simvollarından istifadə edir. (“cari kataloq”) və “..” (ana kataloq). Məsələn: “ ./Pictures/dog.jpg ” o deməkdir ki, hazırda yerləşdiyimiz qovluqda Şəkillər qovluğu, onun içində isə “dog.jpg” faylı var.

    Beləliklə, budur. Proqramınızın “.” istifadə edən yolu varsa. və ya “..”, metod normalize()onları siləcək və onları ehtiva etməyən bir yol əldə edəcək:

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

    Konsol çıxışı:

    C:\Users\Java\nümunələr
    C:\Users\nümunələr

  • Path relativize()— cari və keçən yol arasındakı nisbi yolu hesablayır.

    Misal üçün:

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

    Konsol çıxışı:

    İstifadəçi adı\Desktop\testFile.txt

Metodların tam siyahısı Patholduqca böyükdür. Onların hamısını Oracle sənədlərində tapa bilərsiniz . Biz nəzərdən keçirməyə davam edəcəyik Files.

Fayllar

Files- bu, sinifdən statik metodların köçürüldüyü bir köməkçi sinifdir File. - bu, təxminən və ya Filesilə eynidir , massivlər və kolleksiyalarla deyil, yalnız fayllarla işləyir :) O, faylların və qovluqların idarə edilməsinə yönəlib. Statik metodlardan istifadə edərək biz faylları və qovluqları yarada, silə və köçürə bilərik. Bu əməliyyatlar üçün metodlardan istifadə olunur (kataloqlar üçün - ) və . Onlardan necə istifadə etmək olar: ArraysCollectionsFilescreateFile()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()Burada əvvəlcə iş masasında bir fayl (metod ) yaradırıq , sonra orada bir qovluq yaradırıq (metod Files.createDirectory()). Bundan sonra faylı (metod ) iş masasından bu yeni qovluğa köçürürük Files.move()və sonunda faylı silirik (metod Files.delete()). Konsol çıxışı: Fayl uğurla yaradılıb? true Kataloq uğurla yaradılıbmı? true Faylımız hələ də masaüstündədir? false Faylımız testDirectory-ə köçürülüb? true Fayl hələ də mövcuddur? yalan Diqqət edin:İnterfeys metodları kimi bir çox üsullarPath da obyekti qaytarır . Əksər sinif üsulları da qəbul edir . Burada bir üsul sizin sadiq köməkçiniz olacaq - onu aktiv şəkildə istifadə edin. Başqa nə maraqlıdır ? Köhnə sinifdə həqiqətən çatışmayan şey ! metodu idi. Mühazirənin əvvəlində onun haqqında danışdıq, indi onunla görüşmək vaxtıdır! FilesPathFilesPathPaths.get()FilesFilecopy()
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")));
   }
}
Konsol çıxışı: Fayl uğurla yaradılıb? true Kataloq uğurla yaradılıbmı? true Faylımız hələ də masaüstündədir? true Faylımız testDirectory-ə kopyalanıb? true İndi faylları proqramlı şəkildə kopyalaya bilərsiniz! :) Lakin sinif Filesyalnız faylların özlərini idarə etməyə deyil, həm də onun məzmunu ilə işləməyə imkan verir. Fayla məlumat yazmaq üçün onun bir metodu var write(), oxumaq üçün isə - 3: read()və sonuncunun üzərində ətraflı dayanacağıq readAllBytes(). readAllLines()Niyə bunun üstündə? Çünki çox maraqlı qaytarma növü var - List<String>! Yəni bizə fayldakı sətirlərin siyahısını qaytarır. Əlbəttə ki, bu, məzmunla işləməyi çox rahat edir, çünki bütün fayl, sətir-sətir, məsələn, müntəzəm dövrədə konsola çıxarıla bilər 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);
       }
   }
}
Konsolun çıxışı: Gözəl bir anı xatırlayıram: Qarşımda göründün, Keçən bir baxış kimi, Saf gözəllik dahisi kimi. Çox rahat! :) Bu funksiya Java 7-də ortaya çıxdı. Java 8-də Java-ya funksional proqramlaşdırmanın bəzi elementlərini əlavə edən Stream API meydana çıxdı. Fayllarla işləmək üçün daha zəngin imkanlar daxildir. Təsəvvür edin ki, bizim vəzifəmiz var: faylda “Necə” sözü ilə başlayan bütün sətirləri tapın, onları BÖYÜK RƏFSƏ çevirin və konsola çıxarın. FilesJava 7-də sinifdən istifadə edərək həll yolu necə görünəcək? Bu kimi bir şey:
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);
       }
   }
}
Konsol çıxışı: ORUC GÖRÜŞÜ KİMİ, SAF GÖZƏLLİK DAHİSİ KİMİ. Deyəsən, biz bunu etmişik, amma sizcə belə sadə iş üçün kodumuz bir az... müfəssəl oldu? Java 8 Stream API istifadə edərək həll daha zərif görünür:
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);
   }
}
Eyni nəticəni əldə etdik, lakin daha az kodla! Üstəlik, “oxunurluq”da da itirdiyimizi söyləmək olmaz. Məncə, siz Stream API ilə tanış olmasanız belə, bu kodun nə etdiyini asanlıqla şərh edə bilərsiniz. Qısacası, Stream müxtəlif funksiyaları yerinə yetirə biləcəyiniz elementlər ardıcıllığıdır. Metoddan Stream obyektini alırıq Files.lines()və sonra ona 3 funksiya tətbiq edirik:
  1. Metoddan istifadə edərək, filter()fayldan yalnız "Necə" ilə başlayan sətirləri seçirik.

  2. Metoddan istifadə edərək bütün seçilmiş cərgələrdən keçirik map()və onların hər birini BÖYÜK RƏFSƏ endiririk.

  3. ListYaranan bütün xətləri istifadə etmək üçün birləşdiririk collect().

Çıxışda eyni nəticəni alırıq: ORUC GÖRÜŞÜ KİMİ, SAF GÖZƏLLİK DAHİSİ KİMİ. Bu kitabxananın imkanları haqqında daha çox öyrənmək istəyirsinizsə, bu məqaləni oxumağı məsləhət görürük . Qoyunlarımıza, yəni fayllara qayıdacağıq :) Bu gün nəzərdən keçirəcəyimiz son imkan fayl ağacından keçməkdir . Müasir əməliyyat sistemlərində fayl strukturu ən çox ağac formasını alır: onun kökü var və digər budaqların ayrıla biləcəyi budaqlar var və s. Kataloqlar kök və budaq rolunu oynayır. Məsələn, “ C:// ” kataloqu kök kimi çıxış edə bilər . Ondan iki filial ayrılır: “ C://Yükləmələr ” və “ C://İstifadəçilər ”. Bu filialların hər birindən daha 2 filial var: “ C://Yükləmələr/Şəkillər ”, “ C://Yükləmələr/Video ”, “ C://Users/JohnSmith ”, “ C://Users/Pudge2005 ” . Digər filiallar bu filiallardan ayrılır və s. - ağac belə çıxır. Linux-da bu, təxminən eyni görünür, yalnız orada kataloq kök rolunu oynayır / Fayllar, Yol - 2 İndi təsəvvür edin ki, bizim vəzifəmiz var: kök kataloqunu bilməklə, biz onu keçməliyik, bütün səviyyəli qovluqlara baxmalı və məzmunu olan faylları tapmalıyıq. ehtiyacımız var. “Bizə lazım olan fayl budur!” sətirini ehtiva edən faylları axtaracağıq. Kök kataloqumuz iş masasında yerləşən “testFolder” qovluğu olacaq. İçərisində aşağıdakı məzmun var: Fayllar, Yol - 3level1-a və level1-b qovluqlarının içərisində də qovluqlar var: Fayllar, Yol - 4Fayllar, Yol - 5Bu "ikinci səviyyəli qovluqların" içərisində artıq qovluq yoxdur, yalnız fərdi fayllar var: Fayllar, Yol - 6Fayllar, Yol - 7Biz xüsusi olaraq məzmunu olan 3 fayl təyin edəcəyik. aydın adlarla lazımdır - FileWeNeed1.txt , FileWeNeed2.txt, FileWeNeed3.txt Java istifadə edərək məzmuna görə tapmalı olduğumuz bunlardır. Bunu necə edə bilərik? Bir fayl ağacını keçmək üçün çox güclü bir üsul xilasetmə üçün gəlir - Files.walkFileTree(). Nə etməli olduğumuz budur. Birincisi, bizə lazımdır FileVisitor. FileVisitorfayl ağacını keçmək üçün bütün üsulları təsvir edən xüsusi interfeysdir. Konkret olaraq, faylın məzmununu oxumaq və orada bizə lazım olan mətni ehtiva edib-etmədiyini yoxlamaq üçün məntiqi oraya qoyacağıq. Bizimki belə görünəcək 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;
   }
}
Bu halda bizim sinif miras alır SimpleFileVisitor. FileVisitorBu , yalnız bir metodu ləğv etməli olduğunuz , həyata keçirən bir sinifdir : visitFile(). Burada hər bir kataloqdakı hər bir fayl ilə nə edilməli olduğunu təsvir edirik. Daha mürəkkəb keçid məntiqinə ehtiyacınız varsa, öz tətbiqinizi yazmalısınız FileVisitor. Orada daha 3 üsul tətbiq etməli olacaqsınız:
  • preVisitDirectory()— qovluğa daxil olmamışdan əvvəl yerinə yetirilməli olan məntiq;

  • visitFileFailed()— fayla daxil olmaq mümkün olmadıqda nə etməli (giriş yoxdur və ya digər səbəblər);

  • postVisitDirectory()— qovluğa daxil olduqdan sonra icra edilməli olan məntiq.

Bizim belə bir məntiqimiz yoxdur, ona görə də bizə kifayətdir SimpleFileVisitor. Metodun daxilindəki məntiq visitFile()olduqca sadədir: fayldan bütün sətirləri oxuyun, onlarda bizə lazım olan məzmunun olub-olmadığını yoxlayın və əgər belədirsə, konsolun mütləq yolunu çap edin. Sizə problem yarada biləcək yeganə xətt budur:
return FileVisitResult.CONTINUE;
Əslində hər şey sadədir. Burada sadəcə olaraq fayl daxil edildikdən və bütün lazımi əməliyyatlar tamamlandıqdan sonra proqramın nə etməli olduğunu təsvir edirik. Bizim vəziyyətimizdə ağacın üstündən keçməyə davam etməliyik, buna görə də seçimi seçirik CONTINUE. Ancaq, məsələn, başqa bir vəzifəmiz ola bilər: "Bu, bizə lazım olan fayldır" olan bütün faylları deyil, yalnız bir belə faylı tapmaq . Bundan sonra proqram dayandırılmalıdır. Bu halda, kodumuz tam olaraq eyni görünəcək, lakin break əvəzinə; olardı:
return FileVisitResult.TERMINATE;
Yaxşı, gəlin kodumuzu işə salaq və onun işlədiyini görək.
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());
   }
}
Konsol çıxışı: Tələb olunan fayl tapıldı! C:\Users\Username\Desktop\testFolder\FileWeNeed1.txt Lazım olan fayl tapıldı! C:\Users\Username\Desktop\testFolder\level1-a\level2-aa\FileWeNeed2.txt Tələb olunan fayl tapıldı! C:\Users\Username\Desktop\testFolder\level1-b\level2-bb\FileWeNeed3.txt Əla, biz bunu etdik! :) Haqqında daha çox bilmək istəyirsinizsə , sizə bu məqaləniwalkFileTree() tövsiyə edirəm . Siz həmçinin kiçik bir tapşırığı tamamlaya bilərsiniz - onu adi biri ilə əvəz edin , bütün 4 metodu tətbiq edin və bu proqram üçün bir məqsəd tapın. Məsələn, bütün hərəkətlərinizi qeyd edəcək bir proqram yaza bilərsiniz: fayl və ya qovluğun adını daxil etməzdən əvvəl/sonra konsolda göstərin. Hamısı budur - sonra görüşərik! :) SimpleFileVisitorFileVisitor
Şərhlər
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION