File
. Оның жұмысы туралы мына жерден оқи аласыз . Бірақ Java 7-де тілді жасаушылар файлдармен және каталогтармен жұмыс істеу тәсілін өзгертуге шешім қабылдады. File
Бұған сыныптың бірқатар кемшіліктері себеп болды . copy()
Мысалы, оның файлды бір орыннан екінші орынға көшіруге мүмкіндік беретін әдісі болмады (бұл анық қажет болып көрінетін мүмкіндік). Сонымен қатар, сыныпта - мәндерін File
қайтаратын көптеген әдістер болды boolean
. Қате орын алса, мұндай әдіс қателерді диагностикалауды және олардың себептерін анықтауды өте қиын ететін ерекше жағдайды тастамай, жалған мәнін қайтарады. Бір сыныптың орнына 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
. Біріншіден , одан көптеген утorталық (статикалық) әдістер жойылып, сыныпқа көшірілді Files
. Екіншіден , Path
әдістердің қайтару мәндері реттелген. Сыныпта File
әдістер мынаны String
, мынаны boolean
, мынаны қайтарды File
- оны анықтау оңай болмады. Мысалы, getParent()
жол ретінде ағымдағы файлдың ата-аналық жолын қайтаратын әдіс болды. Бірақ сонымен бірге getParentFile()
бірдей нәрсені қайтаратын әдіс болды, бірақ нысан түрінде File
! Бұл артық екені анық. Сондықтан интерфейсте файлдармен жұмыс істеудің Path
әдісі және басқа әдістері жай ғана нысанды қайтарады . Көптеген опциялар жоқ - бәрі оңай және қарапайым. Оның қандай пайдалы әдістері бар ? Міне, олардың кейбіреулері және олардың жұмысының мысалдары: getParent()
Path
Path
-
getFileName()
— жолдан файл атын қайтарады; -
getParent()
— ағымдағы жолға қатысты «ата-ана» каталогын қайтарады (яғни каталогтар ағашында жоғары тұрған каталог); -
getRoot()
— «түбір» каталогын қайтарады; яғни каталогтар ағашының жоғарғы жағында орналасқан; -
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 ” біз қазір орналасқан каталогта Суреттер қалтасы және оның ішінде “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\мысалдар
C:\Users\мысалдар -
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)); } }
Консоль шығысы:
Пайдаланушы аты\Жұмыс үстелі\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()
). Осыдан кейін біз файлды (әдіс Files.move()
) жұмыс үстелінен осы жаңа қалтаға жылжытамыз және соңында файлды жоямыз (әдіс Files.delete()
). Консоль шығысы: файл сәтті жасалды ма? true Каталог сәтті жасалды ма? 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 Біздің файл әлі жұмыс үстелінде ме? 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);
}
}
}
Консольдің шығарылымы: Бір тамаша сәт есімде: Көз алдымда көріндің, Өтпелі аяндай, Мөлдір сұлудың данышпанындай. Өте ыңғайлы! :) Бұл мүмкіндік Java 7-де пайда болды. Java 8-де Stream API пайда болды , ол Java-ға функционалдық бағдарламалаудың кейбір элементтерін қосты. Оның ішінде файлдарды басқарудың бай мүмкіндіктері. Бізде тапсырма бар деп елестетіп көріңіз: файлдағы «Қалай» сөзінен басталатын барлық жолдарды тауып, оларды БАС РЕГИПКЕ түрлендіріңіз және оларды консольге шығарыңыз. Java 7-де сыныпты пайдаланатын шешім қандай болады Files
? Сол сияқты бірнәрсе:
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);
}
}
}
Консоль шығысы: ОРАЗАҚ КӨРІНІСІНДЕГІ, ТАЗА СҰЛУЛЫҚТЫҢ ДЕНІСІ СИЯҚТЫ. Біз мұны істеген сияқтымыз, бірақ мұндай қарапайым тапсырма үшін біздің codeымыз аздап ... толық болып шықты деп ойламайсыз ба? 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);
}
}
Біз бірдей нәтижеге қол жеткіздік, бірақ әлдеқайда аз codeпен! Оның үстіне, біз «оқылатындықтан» жоғалттық деп айтуға болмайды. Stream API-мен таныс болмасаңыз да, бұл codeтың не істейтіні туралы оңай түсініктеме бере аласыз деп ойлаймын. Бірақ қысқаша айтқанда, ағын - бұл әртүрлі функцияларды орындауға болатын элементтер тізбегі. Біз әдістен Stream нысанын аламыз Files.lines()
, содан кейін оған 3 функцияны қолданамыз:
-
Әдістің көмегімен
filter()
біз файлдан «Қалай» деп басталатын жолдарды ғана таңдаймыз. -
Біз барлық таңдалған жолдарды әдісті қолданып өтіп
map()
, олардың әрқайсысын ҮЛКЕН РЕГИПКЕ дейін азайтамыз. -
Біз барлық алынған жолдарды
List
пайдалану үшін біріктіремізcollect()
.
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
. Бірақ бізде, мысалы, басқа тапсырма болуы мүмкін: «Бұл бізге қажет файл» бар барлық файлдарды емес, тек бір файлды табу . Осыдан кейін бағдарламаны тоқтату керек. Бұл жағдайда біздің code дәл солай көрінеді, бірақ үзіліс орнына; болар еді:
return FileVisitResult.TERMINATE;
Ал, codeымызды іске қосып, оның жұмыс істейтінін көрейік.
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()
, мен сізге осы мақаланы ұсынамын . Сіз сондай-ақ шағын тапсырманы орындай аласыз - оны SimpleFileVisitor
әдеттегіге ауыстырыңыз FileVisitor
, барлық 4 әдісті орындаңыз және осы бағдарламаның мақсатын анықтаңыз. Мысалы, сіз барлық әрекеттеріңізді тіркейтін бағдарламаны жаза аласыз: консольде файлдың немесе қалтаның атын оларды енгізер алдында/кейін көрсету. Барлығы - кейінірек кездескенше! :)
GO TO FULL VERSION