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. File
Bu, 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 File
qaytaran 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ə File
3 sinif meydana çıxdı: Paths
, Path
və Files
. Yaxşı, dəqiq desək, Path
bu 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
Paths
tə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 Path
anlayaq :)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 , Path
metodları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 Path
metod 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()
Path
Path
-
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
falseMetodun 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ğruMetodun 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 var
Path
.
-
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
Path
olduqca 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 Files
ilə 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: 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()
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! 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")));
}
}
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 Files
yalnı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. Files
Java 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:
-
Metoddan istifadə edərək,
filter()
fayldan yalnız "Necə" ilə başlayan sətirləri seçirik. -
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. -
List
Yaranan bütün xətləri istifadə etmək üçün birləşdiririkcollect()
.
Files.walkFileTree()
. Nə etməli olduğumuz budur. Birincisi, bizə lazımdır FileVisitor
. FileVisitor
fayl 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
. FileVisitor
Bu , 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.
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! :) SimpleFileVisitor
FileVisitor
GO TO FULL VERSION