Mga landas
Ang mga landas ay isang napaka-simpleng klase na may isang solong static na pamamaraan: get() . Ito ay nilikha lamang upang makakuha ng Path object mula sa ipinasang string o URI. Wala itong ibang pag-andar. Narito ang isang halimbawa nito sa trabaho:
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");
}
}
Hindi ang pinaka kumplikadong klase, tama ba? :) Well, mayroon din kaming ganitong uri ng Path . Alamin natin kung ano ang Path at bakit ito kailangan :)
Daan
Ang Path , sa pangkalahatan, ay isang muling idinisenyong analogue ng klase ng File . Ito ay mas madaling gamitin kaysa sa File . Una , maraming mga utility (static) na pamamaraan ang kinuha at inilipat sa klase ng Mga File . Pangalawa , ipinataw ang order sa mga return value ng mga pamamaraan ng interface ng Path . Sa klase ng File , ibinalik ng mga pamamaraan ang alinman sa String , o isang boolean , o isang File . Ito ay hindi madaling malaman ito. Halimbawa, nagkaroon ng getParent() method na nagbalik ng string na kumakatawan sa parent path ng kasalukuyang file. Ngunit nagkaroon din ng isanggetParentFile() method, na nagbalik ng parehong bagay ngunit sa anyo ng isang File object! Ito ay malinaw na kalabisan. Alinsunod dito, sa interface ng Path , ang getParent() na pamamaraan at iba pang mga pamamaraan para sa pagtatrabaho sa mga file ay nagbabalik lamang ng isang Path object. Walang tumpok ng mga opsyon — lahat ay madali at simple. Ano ang ilan sa mga kapaki-pakinabang na pamamaraan na mayroon ang Path ? Narito ang ilan sa mga ito at mga halimbawa kung paano sila gumagana:-
getFileName() : ibinabalik ang pangalan ng file mula sa landas;
-
getParent() : ibinabalik ang "magulang" na direktoryo ng kasalukuyang landas (sa madaling salita, ang direktoryo na matatagpuan kaagad sa itaas sa puno ng direktoryo);
-
getRoot() : ibinabalik ang "root" na direktoryo, ibig sabihin, ang direktoryo sa tuktok ng puno ng direktoryo;
-
startsWith() , endsWith() : suriin kung ang landas ay nagsisimula/nagtatapos sa naipasa na landas:
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); } }
Output ng console:
testFile.txt C:\Users\Username\Desktop C:\ true false
Bigyang-pansin kung paano gumagana ang endsWith() na pamamaraan. Sinusuri nito kung ang kasalukuyang landas ay nagtatapos sa naipasa na landas . Sa partikular, kung ito ay nasa path , hindi sa naipasa na string .
Ihambing ang mga resulta ng dalawang tawag na ito:
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")); } }
Output ng console:
false true
Ang endsWith() na pamamaraan ay dapat na maipasa sa isang tunay na landas, hindi lamang isang hanay ng mga character: kung hindi, ang resulta ay palaging mali, kahit na ang kasalukuyang landas ay talagang nagtatapos sa pagkakasunud-sunod ng mga character na iyon (tulad ng kaso sa "estFile.txt "sa halimbawa sa itaas).
Bilang karagdagan, ang Path ay may pangkat ng mga pamamaraan na nagpapasimple sa pagtatrabaho sa ganap (buo) at mga kamag-anak na landas .
-
Ang boolean isAbsolute() ay nagbabalik ng true kung ang kasalukuyang landas ay ganap:
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()); } }
Output ng console:
true
-
Path normalize() : "na-normalize" ang kasalukuyang landas, inaalis ang mga hindi kinakailangang elemento mula dito. Maaaring alam mo na sa mga sikat na operating system ang mga simbolo na "." (kasalukuyang direktoryo) at ".." (direktoryo ng magulang) ay kadalasang ginagamit upang magtalaga ng mga landas. Halimbawa, ang ibig sabihin ng " ./Pictures/dog.jpg " ay ang kasalukuyang direktoryo ay may folder na "Mga Larawan", na naglalaman naman ng "dog.jpg" na file.
Tumingin dito. Kung ang isang path na gumagamit ng "." o ".." ay lilitaw sa iyong programa, ang normalize() na pamamaraan ay aalisin ang mga ito at gagawa ng isang landas na hindi naglalaman ng mga ito:
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()); } }
Output ng console:
C:\Users\Java\examples C:\Users\examples
-
Path relativize() : kinakalkula ang kamag-anak na landas sa pagitan ng kasalukuyang at ng naipasa na landas.
Halimbawa:
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)); } }
Output ng console:
Username\Desktop\testFile.txt
Mga file
Ang mga file ay isang utility class na nagtataglay ng mga static na pamamaraan na kinuha mula sa klase ng File . Ang mga file ay maihahambing sa Arrays o Collections . Ang pagkakaiba ay gumagana ito sa mga file, hindi sa mga array o mga koleksyon :) Nakatuon ito sa pamamahala ng mga file at direktoryo. Gamit ang mga static na pamamaraan ng klase ng Files , maaari tayong lumikha, magtanggal, at maglipat ng mga file at direktoryo. Ginagawa ang mga operasyong ito gamit ang createFile() (para sa mga direktoryo, createDirectory() ), move() , at delete() na mga pamamaraan. Narito kung paano gamitin ang mga ito:
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")));
}
}
Dito muna tayo gumawa ng file ( Files.createFile() method) sa desktop. Pagkatapos ay lumikha kami ng isang folder sa parehong lokasyon ( Files.createDirectory() method). Pagkatapos nito, inililipat namin ang file ( Files.move() method) mula sa desktop papunta sa bagong folder na ito, at sa wakas ay tatanggalin namin ang file ( Files.delete() method). Output ng console:
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
Tandaan:tulad ng mga pamamaraan ng Path
interface, maraming mga pamamaraan ng Files
klase ang nagbabalik ng isangPath
bagay. Karamihan sa mga pamamaraan ng Files
klase ay kumukuha din Path
ng mga bagay bilang mga input. Dito ang Paths.get()
paraan ay magiging iyong tapat na katulong — gamitin ito nang mabuti. Ano pa ang kawili-wili sa Files
? File
Ang talagang kulang sa lumang klase ay isang copy()
pamamaraan! Napag-usapan natin ito sa simula ng araling ito. Ngayon ay oras na upang matugunan ito!
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")));
}
}
Output ng console:
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
Ngayon alam mo na kung paano kopyahin ang mga file sa programmatically! :) Siyempre, Files
hinahayaan ka ng klase na hindi lamang pamahalaan ang isang file mismo, ngunit gumana rin sa mga nilalaman nito. Mayroon itong write()
paraan para sa pagsusulat ng data sa isang file, at lahat ng 3 pamamaraan para sa pagbabasa ng data: read()
, readAllBytes()
, at readAllLines()
Tatalakayin namin nang detalyado ang huli. Bakit yung isa? Dahil mayroon itong napaka-interesante na uri ng pagbabalik: List<String>
! Iyon ay, ibinabalik nito sa amin ang isang listahan ng lahat ng mga linya sa file. Siyempre, ginagawa nitong napaka-maginhawang magtrabaho kasama ang mga nilalaman ng file, dahil ang buong file, linya sa linya, ay maaaring, halimbawa, ay maipakita sa console gamit ang isang ordinaryong for
loop:
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);
}
}
}
Output ng console:
I still recall the wondrous moment:
When you appeared before my sight,
As though a brief and fleeting omen,
Pure phantom in enchanting light.
Super maginhawa! :) Ang kakayahang ito ay lumitaw sa Java 7. Ang Stream API ay lumitaw sa Java 8. Nagdaragdag ito ng ilang elemento ng functional programming sa Java. Kabilang ang mas mahusay na mga kakayahan sa paghawak ng file. Isipin na mayroon kaming sumusunod na gawain: hanapin ang lahat ng mga linya na nagsisimula sa salitang "Bilang", i-convert ang mga ito sa UPPERCASE, at ipakita ang mga ito sa console. Files
Ano ang magiging hitsura ng isang solusyon gamit ang klase sa Java 7? Isang bagay na tulad nito:
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);
}
}
}
Output ng console:
AS THOUGH A BRIEF AND FLEETING OMEN,
PURE PHANTOM IN ENCHANTING LIGHT.
Natapos ang misyon, ngunit hindi mo ba naisip na para sa isang simpleng gawain ang aming code ay naging isang maliit na ... verbose? Gamit ang Stream API ng Java 8, mukhang mas elegante ang solusyon:
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);
}
}
Nakamit namin ang parehong resulta, ngunit may mas kaunting code! Higit pa rito, walang makapagsasabing nawalan na tayo ng "readability". Sa tingin ko madali kang makakapagkomento sa kung ano ang ginagawa ng code na ito, kahit na hindi pamilyar sa Stream API. Sa madaling salita, ang Stream ay isang pagkakasunud-sunod ng mga elemento, kung saan maaari kang magsagawa ng iba't ibang mga operasyon. Kumuha kami ng isang Stream object mula sa Files.lines()
pamamaraan, at pagkatapos ay maglapat ng 3 function dito:
-
Ginagamit namin ang
filter()
paraan upang piliin lamang ang mga linyang iyon mula sa file na nagsisimula sa "As". -
Naglalakad kami sa lahat ng napiling linya gamit ang
map()
pamamaraan at i-convert ang bawat isa sa kanila sa UPPERCASE. -
Ginagamit namin ang
collect()
paraan upang tipunin ang lahat ng natanggap na linya sa isangList
.
AS THOUGH A BRIEF AND FLEETING OMEN,
PURE PHANTOM IN ENCHANTING LIGHT.
Ngayon bumalik tayo sa ating tinapay at mantikilya, iyon ay, mga file :) Ang huling kakayahan na isasaalang-alang natin ngayon ay ang paglalakad sa isang file tree . Sa modernong mga operating system, ang istraktura ng file ay kadalasang mukhang isang puno: ito ay may ugat at may mga sanga, na maaaring magkaroon ng iba pang mga sanga, atbp. Ang ugat at mga sanga ay mga direktoryo. Halimbawa, ang direktoryo na " С:// " ay maaaring ang ugat. Kabilang dito ang dalawang sangay: " C://Downloads " at " C://Users ". Ang bawat isa sa mga sangay na ito ay may dalawang sangay: " C://Downloads/Pictures ", " C://Downloads/Video ", " C://Users/JohnSmith ", " C://Users/Pudge2005". At ang mga sanga na ito naman ay may iba pang mga sanga, atbp. at ito ang dahilan kung bakit tinatawag natin itong puno. Sa Linux, ang istraktura ay magkatulad, ngunit ang / direktoryo ay ang ugat. Ngayon isipin 





Files.walkFileTree ()
. Narito ang kailangan nating gawin. Una, kailangan natin ng FileVisitor
. FileVisitor
ay isang espesyal na interface, kung saan inilarawan ang mga pamamaraan para sa pagtawid sa isang file tree. Sa partikular, doon namin ilalagay ang lohika para sa pagbabasa ng mga nilalaman ng isang file at pagsuri kung naglalaman ito ng teksto na kailangan namin. Narito ang aming FileVisitor
hitsura:
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;
}
}
Sa kasong ito, namamana ng aming klase ang SimpleFileVisitor
. Ito ay isang klase na nagpapatupad ng FileVisitor
, kung saan kailangan nating i-override ang isang paraan lamang: visitFile()
. Dito namin tinutukoy kung ano ang kailangang gawin sa bawat file sa bawat direktoryo. Kung kailangan mo ng mas kumplikadong lohika para sa pagtawid sa istraktura ng file, dapat mong isulat ang iyong sariling pagpapatupad ng FileVisitor
. Kakailanganin mong magpatupad ng 3 pang pamamaraan sa klase na iyon:
-
preVisitDirectory()
: ang lohika na isasagawa bago ipasok ang isang folder; -
visitFileFailed()
: ang lohika na isasagawa kung ang isang file ay hindi mabisita (walang access, o para sa iba pang mga kadahilanan); -
postVisitDirectory()
: ang lohika na isasagawa pagkatapos na magpasok ng isang folder.
SimpleFileVisitor
. Ang lohika sa loob ng visitFile()
pamamaraan ay medyo simple: basahin ang lahat ng mga linya sa file, suriin kung naglalaman ang mga ito ng nilalaman na kailangan namin, at kung gayon, i-print ang ganap na landas sa console. Ang tanging linya na maaaring magdulot sa iyo ng kahirapan ay ang isang ito:
return FileVisitResult.CONTINUE;
Sa totoo lang, ito ay napaka-simple. Dito ay inilalarawan lamang namin kung ano ang dapat gawin ng programa pagkatapos mabisita ang file at maisagawa ang lahat ng kinakailangang operasyon. Sa aming kaso, gusto naming ipagpatuloy ang pagtawid sa puno, kaya pinili namin ang CONTINUE
opsyon. Ngunit, bilang kahalili, maaari tayong magkaroon ng ibang layunin: sa halip na hanapin ang lahat ng mga file na naglalaman ng "Ito ang file na kailangan namin", hanapin lamang ang isang ganoong file . Pagkatapos nito, dapat na wakasan ang programa. Sa kasong ito, ang aming code ay magiging eksaktong pareho, ngunit sa halip na break ay magkakaroon ng:
return FileVisitResult.TERMINATE;
Well, patakbuhin natin ang ating code at tingnan kung gumagana ito.
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());
}
}
Output ng console:
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
Magaling! Gumana ito! :) Maaari mo ring tanggapin ang maliit na hamon na ito: palitan SimpleFileVisitor
ng ordinaryong FileVisitor
, i-override ang lahat ng 4 na pamamaraan, at gumawa ng sarili mong layunin para sa programa. Halimbawa, maaari kang magsulat ng isang programa na nagla-log sa lahat ng mga aksyon nito: ipakita ang pangalan ng file o folder bago o pagkatapos ipasok ang mga ito. Yun lang muna. Hanggang sa muli! :)
GO TO FULL VERSION