Wege
Paths ist eine sehr einfache Klasse mit einer einzigen statischen Methode: get() . Es wurde ausschließlich erstellt, um ein Path- Objekt aus der übergebenen Zeichenfolge oder URI abzurufen. Es hat keine andere Funktionalität. Hier ist ein Beispiel davon bei der Arbeit: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");
}
}
Nicht die komplexeste Klasse, oder? :) Nun, wir haben auch diesen Pfadtyp . Lassen Sie uns herausfinden, was Path ist und warum er benötigt wird :)
Weg
Path ist im Großen und Ganzen ein neu gestaltetes Analogon der File- Klasse. Es ist viel einfacher, damit zu arbeiten als File . Zunächst wurden viele (statische) Dienstprogrammmethoden entfernt und in die Files- Klasse verschoben. Zweitens wurde den Rückgabewerten der Methoden der Path- Schnittstelle eine Reihenfolge auferlegt . In der File- Klasse gaben Methoden entweder einen String , einen Boolean oder einen File zurück . Es war nicht einfach, es herauszufinden. Beispielsweise gab es eine getParent()- Methode, die einen String zurückgab, der den übergeordneten Pfad der aktuellen Datei darstellte. Aber es gab auch einegetParentFile()- Methode, die dasselbe zurückgegeben hat, jedoch in Form eines File- Objekts! Das ist eindeutig überflüssig. Dementsprechend geben in der Path- Schnittstelle dieMethode getParent() und andere Methoden zum Arbeiten mit Dateien einfach ein Path- Objekt zurück. Kein Haufen Optionen – alles ist einfach und unkompliziert. Welche nützlichen Methoden bietet Path ? Hier sind einige davon und Beispiele für ihre Funktionsweise:-
getFileName() : gibt den Dateinamen aus dem Pfad zurück;
-
getParent() : gibt das „übergeordnete“ Verzeichnis des aktuellen Pfads zurück (mit anderen Worten, das Verzeichnis, das sich direkt darüber im Verzeichnisbaum befindet);
-
getRoot() : gibt das „Root“-Verzeichnis zurück, also das Verzeichnis oben im Verzeichnisbaum;
-
StartsWith() , EndsWith() : Überprüfen Sie, ob der Pfad mit dem übergebenen Pfad beginnt/endet:
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); } }
Konsolenausgabe:
testFile.txt C:\Users\Username\Desktop C:\ true false
Achten Sie darauf, wie die Methode „endsWith()“ funktioniert. Es prüft, ob der aktuelle Pfad mit dem übergebenen Pfad endet . Insbesondere, ob es sich im Pfad und nicht im übergebenen String befindet .
Vergleichen Sie die Ergebnisse dieser beiden Aufrufe:
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")); } }
Konsolenausgabe:
false true
Der Methode „endsWith()“ muss ein echter Pfad übergeben werden, nicht nur eine Reihe von Zeichen: Andernfalls ist das Ergebnis immer falsch, auch wenn der aktuelle Pfad tatsächlich mit dieser Zeichenfolge endet (wie es bei „estFile.txt“ der Fall ist). " im Beispiel oben).
Darüber hinaus verfügt Path über eine Gruppe von Methoden, die das Arbeiten mit absoluten (vollständigen) und relativen Pfaden vereinfacht .
-
boolean isAbsolute() gibt true zurück, wenn der aktuelle Pfad absolut ist:
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()); } }
Konsolenausgabe:
true
-
Path normalize() : „normalisiert“ den aktuellen Pfad und entfernt unnötige Elemente daraus. Sie wissen vielleicht, dass in gängigen Betriebssystemen die Symbole „.“ (aktuelles Verzeichnis) und „..“ (übergeordnetes Verzeichnis) werden häufig zur Angabe von Pfaden verwendet. Beispielsweise bedeutet „ ./Pictures/dog.jpg “, dass das aktuelle Verzeichnis über einen Ordner „Pictures“ verfügt, der wiederum eine Datei „dog.jpg“ enthält.
Schau hier. Wenn ein Pfad mit „.“ oder „..“ in Ihrem Programm erscheint, entfernt die normalize()- Methode sie und erstellt einen Pfad, der sie nicht enthält:
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()); } }
Konsolenausgabe:
C:\Users\Java\examples C:\Users\examples
-
Path relativize() : Berechnet den relativen Pfad zwischen dem aktuellen und dem übergebenen Pfad.
Zum Beispiel:
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)); } }
Konsolenausgabe:
Username\Desktop\testFile.txt
Dateien
Files ist eine Dienstprogrammklasse, die die statischen Methoden enthält, die aus der File- Klasse übernommen wurden. Files ist vergleichbar mit Arrays oder Collections . Der Unterschied besteht darin, dass es mit Dateien funktioniert, nicht mit Arrays oder Sammlungen :) Der Schwerpunkt liegt auf der Verwaltung von Dateien und Verzeichnissen. Mit den statischen Methoden der Files- Klasse können wir Dateien und Verzeichnisse erstellen, löschen und verschieben. Diese Vorgänge werden mit den Methoden createFile() (für Verzeichnisse: createDirectory() ), move() und delete() ausgeführt . So verwenden Sie sie: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")));
}
}
Hier erstellen wir zunächst eine Datei ( Methode Files.createFile() ) auf dem Desktop. Dann erstellen wir einen Ordner am selben Ort ( Methode Files.createDirectory() ). Danach verschieben wir die Datei ( Methode Files.move() ) vom Desktop in diesen neuen Ordner und löschen schließlich die Datei ( Methode Files.delete() ). Konsolenausgabe:
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
Notiz:Wie die Methoden der Path
Schnittstelle geben viele Methoden der Files
Klasse einPath
Objekt zurück. Die meisten Methoden der Files
Klasse akzeptieren auch Path
Objekte als Eingaben. Hier Paths.get()
wird die Methode Ihr treuer Helfer sein – nutzen Sie sie sinnvoll. Was ist sonst noch interessant Files
? Was der alten File
Klasse wirklich fehlte, ist eine copy()
Methode! Wir haben zu Beginn dieser Lektion darüber gesprochen. Jetzt ist es an der Zeit, es kennenzulernen!
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")));
}
}
Konsolenausgabe:
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
Jetzt wissen Sie, wie Sie Dateien programmgesteuert kopieren! :) Natürlich Files
können Sie mit der Klasse nicht nur eine Datei selbst verwalten, sondern auch mit deren Inhalt arbeiten. Es verfügt über die write()
Methode zum Schreiben von Daten in eine Datei und alle drei Methoden zum Lesen von Daten: read()
, readAllBytes()
, und readAllLines()
Wir werden uns ausführlich mit der letzten befassen. Warum das? Weil es einen sehr interessanten Rückgabetyp hat: List<String>
! Das heißt, es gibt uns eine Liste aller Zeilen in der Datei zurück. Dadurch ist es natürlich sehr komfortabel, mit den Dateiinhalten zu arbeiten, da die gesamte Datei Zeile für Zeile beispielsweise über eine gewöhnliche for
Schleife auf der Konsole angezeigt werden kann:
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);
}
}
}
Konsolenausgabe:
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 praktisch! :) Diese Fähigkeit erschien in Java 7. Die Stream-API erschien in Java 8. Sie fügt Java einige Elemente der funktionalen Programmierung hinzu. Einschließlich umfangreicherer Funktionen zur Dateiverwaltung. Stellen Sie sich vor, wir haben die folgende Aufgabe: Finden Sie alle Zeilen, die mit dem Wort „As“ beginnen, konvertieren Sie sie in GROSSBUCHSTABEN und zeigen Sie sie auf der Konsole an. Wie würde eine Lösung mit der Files
Klasse in Java 7 aussehen? Etwas wie das:
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);
}
}
}
Konsolenausgabe:
AS THOUGH A BRIEF AND FLEETING OMEN,
PURE PHANTOM IN ENCHANTING LIGHT.
Mission erfüllt, aber glauben Sie nicht, dass sich unser Code für eine so einfache Aufgabe als etwas ... ausführlich erwiesen hat? Mit der Stream-API von Java 8 sieht die Lösung viel eleganter aus:
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);
}
}
Wir haben das gleiche Ergebnis erzielt, aber mit viel weniger Code! Darüber hinaus kann niemand sagen, dass wir die „Lesbarkeit“ verloren haben. Ich denke, Sie können leicht kommentieren, was dieser Code bewirkt, auch ohne mit der Stream-API vertraut zu sein. Kurz gesagt ist ein Stream eine Folge von Elementen, über die Sie verschiedene Operationen ausführen können. Wir erhalten ein Stream-Objekt von der Files.lines()
Methode und wenden dann drei Funktionen darauf an:
-
Wir verwenden die
filter()
Methode, um nur diejenigen Zeilen aus der Datei auszuwählen, die mit „As“ beginnen. -
Wir gehen mit der Methode alle ausgewählten Zeilen durch
map()
und wandeln jede davon in GROSSBUCHSTABEN um. -
Wir verwenden die
collect()
Methode, um alle empfangenen Zeilen in einerList
.
AS THOUGH A BRIEF AND FLEETING OMEN,
PURE PHANTOM IN ENCHANTING LIGHT.
Kehren wir nun zu unserem Brot und Butter zurück, also den Dateien :) Die letzte Funktion, die wir heute betrachten werden, ist das Durchlaufen eines Dateibaums . In modernen Betriebssystemen sieht die Dateistruktur meist wie ein Baum aus: Sie hat einen Stamm und es gibt Zweige, die weitere Zweige haben können usw. Der Stamm und die Zweige sind Verzeichnisse. Beispielsweise kann das Verzeichnis „ С:// “ das Stammverzeichnis sein. Es umfasst zwei Zweige: „ C://Downloads “ und „ C://Users “. Jeder dieser Zweige hat zwei Zweige: „ C://Downloads/Pictures “, „ C://Downloads/Video “, „ C://Users/JohnSmith “, „ C://Users/Pudge2005“.". Und diese Zweige wiederum haben andere Zweige usw. und deshalb nennen wir es einen Baum. Unter Linux ist die Struktur ähnlich, aber das / -Verzeichnis 





Files.walkFileTree ()
. Folgendes müssen wir tun. Zuerst brauchen wir eine FileVisitor
. FileVisitor
ist eine spezielle Schnittstelle, in der die Methoden zum Durchlaufen eines Dateibaums beschrieben werden. Hier werden wir insbesondere die Logik zum Lesen des Inhalts einer Datei und zum Überprüfen, ob sie den von uns benötigten Text enthält, unterbringen. So FileVisitor
sieht unser aus:
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;
}
}
In diesem Fall erbt unsere Klasse SimpleFileVisitor
. Dies ist eine Klasse, die implementiert FileVisitor
, in der wir nur eine Methode überschreiben müssen: visitFile()
. Hier definieren wir, was mit jeder Datei in jedem Verzeichnis geschehen soll. Wenn Sie eine komplexere Logik zum Durchlaufen der Dateistruktur benötigen, sollten Sie Ihre eigene Implementierung von schreiben FileVisitor
. Sie müssten drei weitere Methoden in dieser Klasse implementieren:
-
preVisitDirectory()
: die Logik, die vor dem Betreten eines Ordners ausgeführt werden muss; -
visitFileFailed()
: die Logik, die ausgeführt werden soll, wenn eine Datei nicht aufgerufen werden kann (kein Zugriff oder aus anderen Gründen); -
postVisitDirectory()
: die Logik, die nach dem Betreten eines Ordners ausgeführt werden soll.
SimpleFileVisitor
. Die Logik innerhalb der visitFile()
Methode ist recht einfach: Lesen Sie alle Zeilen in der Datei, prüfen Sie, ob sie den benötigten Inhalt enthalten, und geben Sie in diesem Fall den absoluten Pfad auf der Konsole aus. Die einzige Zeile, die Ihnen Schwierigkeiten bereiten könnte, ist diese:
return FileVisitResult.CONTINUE;
Eigentlich ist das ganz einfach. Hier beschreiben wir lediglich, was das Programm tun soll, nachdem die Datei aufgerufen und alle erforderlichen Vorgänge ausgeführt wurden. In unserem Fall möchten wir den Baum weiter durchqueren, also wählen wir die CONTINUE
Option. return FileVisitResult.TERMINATE;
Nun, lassen Sie uns unseren Code ausführen und sehen, ob er funktioniert.
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());
}
}
Konsolenausgabe:
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
Exzellent! Es funktionierte! :) Sie könnten auch diese kleine Herausforderung annehmen: Ersetzen Sie sie SimpleFileVisitor
durch eine gewöhnliche FileVisitor
, überschreiben Sie alle 4 Methoden und überlegen Sie sich Ihren eigenen Zweck für das Programm. Sie könnten beispielsweise ein Programm schreiben, das alle seine Aktionen protokolliert: den Namen der Datei oder des Ordners vor oder nach der Eingabe anzeigen. Das ist alles für den Moment. Bis bald! :) :)
GO TO FULL VERSION