OCPtech

Java NIO.2

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

 

 

Leave a Reply

Your email address will not be published.