Non blocking IO in Java, released with Java 7.
Path
Path represents a path on the storage system to a directory or file. Conceptually it is a replacement for the java.io.File class.
Path path = Paths.get(/bla/bli/blu/blue.txt);
Paths is the factory class for the interface Path. The Paths class contains static factory methods that return a Path.
Path is the interface that represents the path to a file. It contains methods to get information about the path but not modify it.
Files
This class exists of static methods that operate on files and directories.
Files.move(Paths.get("/some/file.txt"), Paths.get("/some/otherfile.txt");
List<String> content = Files.readAllLines(Paths.get("/this/file.txt");
Stream<Path> paths = Files.lines(Paths.get("/my/dir/file.txt");
File Attributes
Metadata is data that provides info about other data. E.g. the creation date of a file.
BasicFileAttributes attributes = Files.readAttributes(path, BasicFileAttributes.class); BasicFileAttributeView view = Files.getFileAttributeView(path, BasicFileAttributeView.class);
BasicFileAttributes provide read only access to the file metadata.
BasicfileAttributeView gives you the opportunity to change the metadata.
Examples
Personally I think the concept is a lot clearer with some advantages. So here we go.
( remember that . means the current directory and .. makes you go one level up in the directory tree)
1. Paths
public static void main(String[] args) throws IOException {
Path desktop = Paths.get("Users/root/Desktop");
IntStream.range(0, desktop.getNameCount())
.forEach((i -> System.out.printf("Element %d is: %s " + System.lineSeparator(), i, desktop.getName(i))));
System.out.println(Paths.get("."));
System.out.println(Paths.get(".").toRealPath());
System.out.println(Paths.get("./level1/level2/../../level1/.././level1/level2").normalize());
System.out.println(Paths.get(".").toAbsolutePath());
}
Output:
Element 0 is: Users Element 1 is: root Element 2 is: Desktop . /Users/nivh/Training/OCP level1/level2 /Users/nivh/Training/OCP/.
- define a path to the Desktop directory
- Print the elements of this path on different lines
- Define some other paths to experiment
- “.” means the relative path to the current active directory
- toRealPath() provides an absolute path if the directory actually exists (if not it throws an exception)
- normalize() can simplify a relative path by removing the redundant parts
- toAbsolutepath() converts a relative path to an absolute path
2. Files
Given a file original.txt that contains:
hello
there
public static void main (String[] args) throws IOException {
Path path = Paths.get("original.txt");
Files.readAllLines(path).forEach(System.out::println);
Files.lines(path).filter(s -> s.startsWith("h")).forEach(System.out::println);
}
hello there hello
- readAllLines returns a list of Strings. Every String corresponds to a line in the file.
- lines(Path path) returns a stream of Strings. Every one of these Strings is a line in the file. Stream permits us to use stream operations on it like filter
3. Files & Java 8
public class CreateAndDeleteDirs {
public static void main(String[] args) {
Path path = Paths.get("9_NIO2/src/main/resources/level1a/level2a/../../level1b/../level1c/level2b/level3a");
Path current = Paths.get("9_NIO2/src/main/resources/");
try {
Files.createDirectories(path);
CreateAndDeleteDirs.walkAndPrint(current);
System.out.println("Number of subdirs: " + CreateAndDeleteDirs.countSubDirs(current));
CreateAndDeleteDirs.deleteDirectoryStream(current);
System.out.println("Deleted dirs");
System.out.println("Number of subdirs: " + CreateAndDeleteDirs.countSubDirs(current));
} catch (IOException e ) {
System.out.println("Cannot create directories: " + e);
}
}
private static void walkAndPrint(Path path) throws IOException{
Files.walk(path)
.filter(p -> Files.isDirectory(p))
.map(p -> p.toAbsolutePath())
.forEach(System.out::println);
}
private static void deleteDirectoryStream(Path path) throws IOException {
Files.walk(path)
.sorted(Comparator.reverseOrder())
.filter(p -> p != path)
.map(Path::toFile)
.forEach(File::delete);
}
private static long countSubDirs(Path path) throws IOException{
return Files.find(
path,
100, // how deep do we want to descend
(p, a) -> a.isDirectory()
).count() - 1;
}
}
Outputs:
/Users/user/Training/OCP/9_NIO2/src/main/resources /Users/user/Training/OCP/9_NIO2/src/main/resources/level1a /Users/user/Training/OCP/9_NIO2/src/main/resources/level1a/level2a /Users/user/Training/OCP/9_NIO2/src/main/resources/level1b /Users/user/Training/OCP/9_NIO2/src/main/resources/level1c /Users/user/Training/OCP/9_NIO2/src/main/resources/level1c/level2b /Users/user/Training/OCP/9_NIO2/src/main/resources/level1c/level2b/level3a Number of subdirs: 6 Deleted dirs Number of subdirs: 0
- all different paths in the current variable are created
- all these different paths are printed as an absolute path
- we count the number of subdirectories (that’s why the method contains a count() – 1, which subtracts the current directory)
- recursively remove all the new subdirectories
- count the subdirectories (should now be zero)
4. BasicFileAttributes & BasicFileAttributeView
public class UseFileAttributes {
public static void main(String[] args) throws IOException {
Path path = Paths.get("original.txt");
// when getting the file view you can modify the props
BasicFileAttributeView view = Files.getFileAttributeView(path, BasicFileAttributeView.class);
BasicFileAttributes data = view.readAttributes();
System.out.println("Filesize: " + data.size());
System.out.println("LastAccessTime was: " + data.lastAccessTime());
System.out.println("lastModifiedTime was: " + data.lastModifiedTime());
waitALittle(3);
FileTime now = FileTime.from(Instant.now());
System.out.println("Now is: " + now);
view.setTimes(null, now, null);
FileTime lastMT = FileTime.fromMillis(data.lastModifiedTime().toMillis() + 80_000);
System.out.println("LastMT is: " + lastMT);
view.setTimes(lastMT , null, null);
BasicFileAttributes newData = view.readAttributes();
System.out.println("LastAccessTime is " + newData.lastAccessTime());
System.out.println("LastModifiedtime is " + newData.lastModifiedTime());
}
static void waitALittle(int seconds){
try {
TimeUnit.SECONDS.sleep(seconds);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Outputs:
Filesize: 11 LastAccessTime was: 2018-12-26T18:25:16Z lastModifiedTime was: 2018-12-21T21:59:34Z Now is: 2018-12-26T18:27:10.982Z LastAccessTime is 2018-12-26T18:27:10Z LastModifiedtime is 2018-12-21T22:00:54Z
- get a View on the file attributes and the attributes itself
- print the filesize in bytes
- print the current lastAccessTime and lastModifiedTime of the file
- change these values
- print the new lastAccessTime and lastModifiedTime