File
. Анын иши тууралуу бул жерден окуй аласыз . Бирок Java 7де тилди жаратуучулар файлдар жана каталогдор менен иштөө ыкмасын өзгөртүүнү чечишкен. File
Буга класстын бир катар кемчorктери себеп болгон . Мисалы, анда copy()
файлды бир жерден экинчи жерге көчүрүүгө мүмкүндүк бере турган ыкма болгон эмес (көрүнүп тургандай, керек болгон функция). Мындан тышкары, класста -values File
кайтарган бир топ методдор бар болчу boolean
. Ката пайда болсо, мындай ыкма каталарды диагностикалоону жана алардын себептерин аныктоону абдан кыйындаткан өзгөчөлүктү ыргытуунун ордуна жалганды кайтарат. Бир класстын ордуна File
3 класс пайда болду: Paths
, Path
жана Files
. Тактап айтканда, Path
бул класс эмес, интерфейс. Келгиле, алар бири-биринен кандайча айырмаланарын жана алардын ар бири эмне үчүн керек экенин карап көрөлү. Эң оңой нерседен баштайлы - Paths
.
Жолдор
Paths
бир статикалык ыкмасы менен абдан жөнөкөй класс болуп саналат get()
. Ал өткөн саптан же URIдан типтеги an objectти алуу үчүн гана түзүлгөн 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");
}
}
Эң кыйын класс эмес, туурабы? :) Ооба, биз типтеги an object алгандыктан , анын эмне экенин жана ал эмне үчүн керек экенин Path
билели :)Path
Жол
Path
, жалпысынан алганда, File
. Аны менен иштөө бир топ жеңorрээк File
. Биринчиден , андан көптөгөн пайдалуу (статикалык) методдор алынып салынган жана класска көчүрүлгөн Files
. Экинчиден , Path
ыкмалардын кайтарым маанилери буйрук кылынган. Класста File
методдор муну String
, тигини boolean
, тигини кайтарды File
- аны аныктоо оңой болгон жок. Мисалы, getParent()
учурдагы файлдын аталык жолун сап катары кайтарган ыкма бар болчу. Бирок ошол эле учурда бир эле нерсени кайтарган ыкма бар болчу getParentFile()
, бирок an object түрүндө File
! Бул ачык эле ашыкча. Ошондуктан, интерфейсте файлдар менен иштөөнүн Path
методу жана башка ыкмалары жөн гана an objectти кайтарат . Көптөгөн варианттар жок - баары оңой жана жөнөкөй. Анын кандай пайдалуу ыкмалары бар ? Бул жерде алардын кээ бирлери жана алардын ишинин мисалдары: 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()
— эгерде учурдагы жол абсолюттук болсо, чындыкты кайтарат: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)); } }
Консолдук чыгаруу:
Username\Desktop\testFile.txt
Path
абдан чоң. Алардын баарын Oracle documentтеринен таба аласыз . Биз карап чыгууну улантабыз 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()
). Консолдун чыгышы: Файл ийгorктүү түзүлдүбү? true Каталог ийгorктүү түзүлдүбү? true Биздин файл дагы деле иш тактадабы? false Биздин файл testDirectory'ге жылдырылдыбы? true Файл дагы эле барбы? жалган Көңүл буруу:Интерфейс ыкмалары сыяктуу эле Path
, көптөгөн методдор Files
an objectти кайтарат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")));
}
}
Консолдун чыгышы: Файл ийгorктүү түзүлдүбү? true Каталог ийгorктүү түзүлдүбү? 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 үчүн функционалдык программалоонун кээ бир элементтерин кошкон. Анын ичинде файлдар менен иштөө үчүн бай мүмкүнчүлүктөр. Элестеткиле, бизде тапшырма бар: файлдагы "Кантип" деген сөз менен башталган бардык саптарды табыңыз, аларды ЖОГОРКУ РЕФЕРАга айлантыңыз жана аларды консолго чыгарыңыз. Files
Java 7де классты колдонуу чечими кандай болот ? Бул сыяктуу бир нерсе:
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 - бул ар кандай функцияларды аткара турган элементтердин ырааттуулугу. Биз методдон Stream an objectисин алабыз 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