File
. Uning ishi haqida bu yerda o'qishingiz mumkin . Ammo Java 7 da til yaratuvchilari fayllar va kataloglar bilan ishlash usullarini o'zgartirishga qaror qilishdi. Bu sinfning File
bir qator kamchiliklarga ega bo'lganligi bilan bog'liq edi. copy()
Misol uchun, unda faylni bir joydan ikkinchi joyga nusxalash imkonini beradigan usul yo'q edi (ko'rinishidan aniq zarur xususiyat). Bundan tashqari, sinfda qiymatlarni File
qaytaradigan juda ko'p usullar mavjud edi . boolean
Agar xatolik yuzaga kelsa, bunday usul istisnodan ko'ra noto'g'ri qaytaradi, bu xatolarni tashxislash va ularning sabablarini aniqlashni juda qiyinlashtiradi. Bitta sinf o'rniga File
3 ta sinf paydo bo'ldi: Paths
, Path
va Files
. Aniqrog'i, Path
bu sinf emas, balki interfeys. Keling, ular bir-biridan qanday farq qilishini va ularning har biri nima uchun kerakligini aniqlaylik. Eng oson narsadan boshlaylik - Paths
.
Yo'llar
Paths
bitta statik usulga ega bo'lgan juda oddiy sinfdir get()
. U faqat o'tkazilgan satr yoki URI dan turdagi ob'ektni olish uchun yaratilgan Path
. Uning boshqa funksiyasi yo'q. Mana uning ishiga misol:
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");
}
}
Eng qiyin sinf emas, to'g'rimi? :) Xo'sh, bizda turdagi ob'ekt bor ekan , keling, u nima ekanligini va nima uchun kerakligini Path
aniqlaylik :)Path
Yo'l
Path
, umuman olganda, ning qayta ishlangan analogidir File
. U bilan ishlashga qaraganda ancha oson File
. Birinchidan , undan ko'plab yordamchi (statik) usullar olib tashlandi va sinfga ko'chirildi Files
. Ikkinchidan , Path
usullarning qaytish qiymatlari buyurtma qilingan. Sinfda File
usullar buni String
, buni boolean
, buni qaytardi File
- buni aniqlash oson emas edi. getParent()
Misol uchun, joriy fayl uchun asosiy yo'lni satr sifatida qaytaradigan usul mavjud edi . Ammo ayni paytda getParentFile()
xuddi shu narsani qaytaradigan usul bor edi, lekin ob'ekt shaklida File
! Bu aniq ortiqcha. Shuning uchun, interfeysda fayllar bilan ishlashning Path
usuli getParent()
va boshqa usullari shunchaki ob'ektni qaytaradi Path
. Ko'p variantlar yo'q - hamma narsa oson va sodda. Uning qanday foydali usullari bor Path
? Mana ulardan ba'zilari va ularning ishlariga misollar:
-
getFileName()
— fayl nomini yo‘ldan qaytaradi; -
getParent()
— joriy yo‘lga nisbatan “ota” katalogini qaytaradi (ya’ni kataloglar daraxtida yuqoriroq joylashgan katalog); -
getRoot()
— “ildiz” katalogini qaytaradi; ya'ni katalog daraxtining tepasida joylashgan; -
startsWith()
,endsWith()
— yoʻl oʻtgan yoʻl bilan boshlanishi/tugashini tekshiring: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 chiqishi:
testFile.txt
C:\Users\Username\Desktop
C:\
true
falseUsul qanday ishlashiga e'tibor bering
endsWith()
. Joriy yo'l o'tgan yo'l bilan tugashini tekshiradi . Bu belgilar to'plamida emas , balki yo'lda .Ushbu ikkita qo'ng'iroq natijalarini solishtiring:
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 chiqishi:
yolg'on
haqiqatUsulga
endsWith()
faqat belgilar to'plamini emas, balki to'liq yo'lni o'tkazishingiz kerak: aks holda, joriy yo'l aslida bunday belgilar ketma-ketligi bilan tugasa ham, natija har doim noto'g'ri bo'ladi ("estFile.txt" misolida bo'lgani kabi. ” yuqoridagi misolda).Bundan tashqari, mutlaq (to'liq) va nisbiy yo'llar bilan ishlashni soddalashtiradigan bir guruh usullar mavjud
Path
.
-
boolean isAbsolute()
— joriy yoʻl mutlaq boʻlsa, true qiymatini qaytaradi: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 chiqishi:
rost
-
Path normalize()
- joriy yo'lni "normallashtiradi", undan keraksiz elementlarni olib tashlaydi. Mashhur operatsion tizimlar yo'llarni belgilashda ko'pincha "." belgilaridan foydalanishini bilishingiz mumkin. (“joriy katalog”) va “..” (ota-ona katalogi). Masalan: “ ./Pictures/dog.jpg ” biz hozir joylashgan katalogda “Rasmlar” papkasi va uning ichida “dog.jpg” fayli borligini bildiradi.Demak, bu yerda. Agar dasturingizda "." dan foydalanadigan yo'l bo'lsa. yoki "..", usul
normalize()
ularni o'chiradi va ularni o'z ichiga olmaydigan yo'lni oladi: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 chiqishi:
C:\Users\Java\misollar
C:\Users\misollar -
Path relativize()
— joriy va oʻtgan yoʻl orasidagi nisbiy yoʻlni hisoblab chiqadi.Masalan:
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 chiqishi:
Foydalanuvchi nomi\Desktop\testFile.txt
Path
juda katta. Ularning barchasini Oracle hujjatlarida topishingiz mumkin . Biz ko'rib chiqishga o'tamiz Files
.
Fayllar
Files
- bu sinfdan statik usullar ko'chirilgan yordamchi sinf File
. Files
- bu taxminan Arrays
yoki bilan bir xil Collections
, faqat u massivlar va to'plamlar bilan emas, balki fayllar bilan ishlaydi :) U fayllar va kataloglarni boshqarishga qaratilgan. Statik usullardan foydalanib Files
, biz fayllar va kataloglarni yaratishimiz, o'chirishimiz va ko'chirishimiz mumkin. Ushbu operatsiyalar uchun usullar qo'llaniladi createFile()
(kataloglar uchun - createDirectory()
), move()
va delete()
. Ulardan qanday foydalanish kerak:
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")));
}
}
Bu erda biz avval ish stolida fayl (usul Files.createFile()
) yaratamiz, keyin u erda papka yaratamiz (usul Files.createDirectory()
). Shundan so'ng, biz faylni (usul Files.move()
) ish stolidan ushbu yangi papkaga o'tkazamiz va oxirida faylni o'chirib tashlaymiz (usul Files.delete()
). Konsol chiqishi: fayl muvaffaqiyatli yaratildimi? true Katalog muvaffaqiyatli yaratildimi? rost Bizning faylimiz ish stolida hamon bormi? false Bizning faylimiz testDirectory-ga ko'chirildimi? true Fayl hali ham mavjudmi? yolg'on Diqqat qilish:Interfeys usullari kabi Path
, ko'p usullar Files
ob'ektni qaytaradiPath
. Ko'pgina sinf usullari Files
ham qabul qiladi Path
. Bu erda usul sizning ishonchli yordamchingizga aylanadi Paths.get()
- undan faol foydalaning. Yana nima qiziq Files
? Eski sinfga haqiqatdan ham ! File
usuli etishmayotgan edi. copy()
Biz u haqida ma'ruza boshida gaplashdik, endi u bilan uchrashish vaqti keldi!
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 chiqishi: fayl muvaffaqiyatli yaratildimi? true Katalog muvaffaqiyatli yaratildimi? rost Bizning faylimiz ish stolida hamon bormi? rost Faylimiz testDirectory-ga ko'chirildimi? true Endi siz fayllarni dasturiy tarzda nusxalashingiz mumkin! :) Lekin sinf Files
nafaqat fayllarni o'zi boshqarishga, balki uning mazmuni bilan ishlashga ham imkon beradi. Faylga ma'lumot yozish uchun uning usuli mavjud write()
, va o'qish uchun - 3: read()
va readAllBytes()
biz readAllLines()
ikkinchisiga batafsil to'xtalib o'tamiz. Nega unda? Chunki u juda qiziqarli qaytish turiga ega - List<String>
! Ya'ni, u bizga fayldagi qatorlar ro'yxatini qaytaradi. Albatta, bu kontent bilan ishlashni juda qulay qiladi, chunki butun fayl, masalan, satr bo'yicha, konsolga oddiy tsiklda chiqarilishi mumkin 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);
}
}
}
Konsol chiqishi: Ajoyib bir lahzani eslayman: Sen mening oldimda paydo bo'lding, O'tkinchi vahiy kabi, Sof go'zallik dahosi kabi. Juda qulay! :) Bu xususiyat Java 7 da paydo bo'ldi. Java 8 da Stream API paydo bo'ldi , u Java-ga funktsional dasturlashning ba'zi elementlarini qo'shdi. Fayllar bilan ishlash uchun yanada boy imkoniyatlarni o'z ichiga oladi. Tasavvur qiling-a, bizda vazifa bor: fayldagi "Qanday qilib" so'zi bilan boshlanadigan barcha satrlarni toping, ularni YUQORI CASE ga aylantiring va konsolga chiqaring. Files
Java 7 da sinfdan foydalangan holda yechim qanday ko'rinishga ega bo'ladi ? Shunga o'xshash narsa:
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 chiqishi: RO'ZA KO'RISH, SOF GO'ZALLIK DHOHISI DAHALI. Biz buni bajarganga o'xshaymiz, lekin shunday oddiy vazifa uchun kodimiz biroz... batafsil bo'lib chiqdi deb o'ylamaysizmi? Java 8 Stream API yordamida yechim ancha oqlangan ko'rinadi:
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);
}
}
Biz bir xil natijaga erishdik, lekin kamroq kod bilan! Bundan tashqari, biz "o'qilishi" bo'yicha yo'qotdik, deb aytish mumkin emas. O'ylaymanki, siz Stream API bilan tanish bo'lmasangiz ham, ushbu kod nima qilishini osongina izohlashingiz mumkin. Qisqasi, Stream - bu turli funktsiyalarni bajarishingiz mumkin bo'lgan elementlar ketma-ketligi. Usuldan Stream ob'ektini olamiz Files.lines()
va unga 3 ta funktsiyani qo'llaymiz:
-
Usuldan foydalanib,
filter()
biz fayldan faqat "Qanday qilib" bilan boshlanadigan qatorlarni tanlaymiz. -
Usul yordamida tanlangan barcha qatorlarni ko'rib chiqamiz
map()
va ularning har birini YUQORI HARF ga qisqartiramiz. -
List
Olingan barcha chiziqlarni ishlatish uchun birlashtiramizcollect()
.
Files.walkFileTree()
. Mana nima qilishimiz kerak. Birinchidan, bizga kerak FileVisitor
. FileVisitor
fayl daraxtini kesib o'tishning barcha usullarini tavsiflovchi maxsus interfeysdir. Xususan, biz fayl mazmunini o'qish va unda bizga kerak bo'lgan matn mavjudligini tekshirish uchun mantiqni qo'yamiz. Bizniki shunday ko'rinadi 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 holda sinfimiz dan meros oladi SimpleFileVisitor
. Bu ni amalga oshiradigan sinf bo'lib FileVisitor
, unda siz faqat bitta usulni bekor qilishingiz kerak: visitFile()
. Bu erda biz har bir katalogdagi har bir fayl bilan nima qilish kerakligini tasvirlaymiz. Agar sizga murakkabroq o'tish mantig'i kerak bo'lsa, o'zingizning dasturingizni yozishingiz kerak FileVisitor
. U erda siz yana 3 ta usulni qo'llashingiz kerak bo'ladi:
-
preVisitDirectory()
— papkaga kirishdan oldin bajarilishi kerak bo'lgan mantiq; -
visitFileFailed()
— faylga kirish imkoni boʻlmasa, nima qilish kerak (kirish imkoni boʻlmasa yoki boshqa sabablarga koʻra); -
postVisitDirectory()
— papkaga kirgandan keyin bajarilishi kerak bo'lgan mantiq.
SimpleFileVisitor
. Usul ichidagi mantiq visitFile()
juda oddiy: fayldagi barcha satrlarni o'qing, ular bizga kerakli tarkibni o'z ichiga olganligini tekshiring va agar shunday bo'lsa, konsolga mutlaq yo'lni chop eting. Sizga muammo tug'dirishi mumkin bo'lgan yagona qator bu:
return FileVisitResult.CONTINUE;
Aslida, hamma narsa oddiy. Bu erda fayl kiritilgandan va barcha kerakli operatsiyalar bajarilgandan so'ng dastur nima qilishi kerakligini oddiygina tasvirlab beramiz. Bizning holatda, biz daraxtni kesib o'tishni davom ettirishimiz kerak, shuning uchun biz variantni tanlaymiz CONTINUE
. Ammo, masalan, bizda boshqa vazifa bo'lishi mumkin: "Bu bizga kerak bo'lgan fayl" ni o'z ichiga olgan barcha fayllarni emas, faqat bitta faylni topish . Shundan so'ng, dastur tugatilishi kerak. Bu holda bizning kodimiz aynan bir xil ko'rinadi, lekin break o'rniga; bo'lardi:
return FileVisitResult.TERMINATE;
Keling, kodimizni ishga tushiramiz va u ishlaydimi yoki yo'qligini tekshiramiz.
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 chiqishi: kerakli fayl topildi! C:\Users\Username\Desktop\testFolder\FileWeNeed1.txt Kerakli fayl topildi! C:\Users\Username\Desktop\testFolder\level1-a\level2-aa\FileWeNeed2.txt Kerakli fayl topildi! C:\Users\Username\Desktop\testFolder\level1-b\level2-bb\FileWeNeed3.txt Ajoyib, biz buni uddaladik! :) Agar siz haqida ko'proq bilmoqchi bo'lsangiz , sizga ushbu maqolaniwalkFileTree()
tavsiya qilaman . Bundan tashqari, siz kichik vazifani bajarishingiz mumkin - uni oddiy bilan almashtiring , barcha 4 usulni qo'llang va ushbu dastur uchun maqsadni aniqlang. Misol uchun, siz barcha harakatlaringizni jurnalga yozib qo'yadigan dastur yozishingiz mumkin: ularni kiritishdan oldin/keyin konsolda fayl yoki papka nomini ko'rsating. Hammasi shu - keyinroq ko'rishguncha! :) SimpleFileVisitor
FileVisitor
GO TO FULL VERSION