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