Java I/O and NIO.2

NIO.2 cookbook, Part 2

Part 2 of a 3-part series on NIO.2 presents path-related recipes, file/directory-testing recipes, and attribute-oriented recipes

Java I/O and NIO.2

Show More
1 2 3 Page 3
Page 3 of 3

Listing 7. PathAttrib.java (version 2)

import java.io.IOException;

import java.nio.file.Files;
import java.nio.file.FileSystem;
import java.nio.file.FileSystems;
import java.nio.file.Path;
import java.nio.file.Paths;

public class PathAttrib
{
   public static void main(String[] args) throws IOException
   {
      boolean isACL = false;
      boolean isDOS = false;

      FileSystem defFS = FileSystems.getDefault();
      for (String fileAttrView : defFS.supportedFileAttributeViews())
      {
         System.out.printf("Default file system supports: %s%n", fileAttrView);
         if (fileAttrView.equals("acl"))
            isACL = true;
         if (fileAttrView.equals("dos"))
            isDOS = true;
      }
      System.out.println();

      if (args.length != 1)
      {
         System.err.println("usage: java PathAttrib path-object");
         return;
      }

      Path path = Paths.get(args[0]);

      // Output basic attributes, which are always supported.

      System.out.println("Basic attributes:");
      String[] attrNames =
      {
         "lastModifiedTime",
         "lastAccessTime",
         "creationTime",
         "size",
         "isRegularFile",
         "isDirectory",
         "isSymbolicLink",
         "isOther", // something other that a regular file, directory, or 
                    // symbolic link
         "fileKey"  // an object that uniquely identifies the given file, or 
                    // null when a file key is not available.
      };
      for (String attrName: attrNames)
         System.out.printf("%s: %s%n", attrName,
                           Files.getAttribute(path, "basic:" + attrName));
      System.out.println();

      // Output ACL owner attribute when this view is supported.

      if (isACL)
      {
         System.out.println("ACL attributes:");
         System.out.printf("Owner: %s%n%n", 
                           Files.getAttribute(path, "acl:owner"));
      }

      // Output DOS attributes when this view is supported.

      if (isDOS)
      {
         System.out.println("DOS attributes:");
         attrNames = new String[] { "readonly", "hidden", "system", "archive" };
         for (String attrName: attrNames)
           System.out.printf("%s: %s%n", attrName,
                             Files.getAttribute(path, "dos:" + attrName));
         System.out.println();
      }
   }
}

Compile Listing 7 and run the application. For example, I observe the following output from java PathAttrib PathAttrib.java:

Default file system supports: acl
Default file system supports: basic
Default file system supports: owner
Default file system supports: user
Default file system supports: dos

Basic attributes:
lastModifiedTime: 2015-03-18T19:36:47.435624Z
lastAccessTime: 2015-03-18T19:21:16.681388Z
creationTime: 2015-03-18T19:21:16.681388Z
size: 2417
isRegularFile: true
isDirectory: false
isSymbolicLink: false
isOther: false
fileKey: null

ACL attributes:
Owner: Owner-PC\Owner (User)

DOS attributes:
readonly: false
hidden: false
system: false
archive: true

Getting and setting multiple attributes

Q: I've heard that it's more efficient to read attributes in bulk as opposed to reading them individually. How do I read attributes in bulk?

A: Files declares a pair of static methods for reading attributes in bulk:

  • <A extends BasicFileAttributes> A readAttributes(Path path, Class<A> type, LinkOption... options)
  • Map<String, Object> readAttributes(Path path, String attributes, LinkOption... options)

The first method returns a java.nio.file.attribute.BasicFileAttributes or subinterface object containing all attribute values for the specified type. Call various methods on the returned object to obtain these values.

The second method returns a map containing the names and values for all attributes identified by the attributes argument, which has the form [view-name:]attribute-list; for example, "posix:permissions,owner,size".

Listing 8 presents an application that demonstrates these methods. The application calls each method to obtain the basic file attributes for a Path object argument and then outputs the values.

Listing 8. PathAttrib.java (version 3)

import java.io.IOException;

import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

import java.nio.file.attribute.BasicFileAttributes;

import java.util.Map;
import java.util.TreeMap;

public class PathAttrib
{
   public static void main(String[] args) throws IOException
   {
      if (args.length != 1)
      {
         System.err.println("usage: java PathAttrib path-object");
         return;
      }

      Path path = Paths.get(args[0]);

      BasicFileAttributes attrs;
      attrs = Files.readAttributes(path, BasicFileAttributes.class);

      System.out.printf("Basic Attributes for %s...%n%n", path);

      System.out.printf("creationTime: %s%n", attrs.creationTime());
      System.out.printf("fileKey: %s%n", attrs.fileKey());
      System.out.printf("isDirectory: %b%n", attrs.isDirectory());
      System.out.printf("isOther: %b%n", attrs.isOther());
      System.out.printf("isRegularFile: %b%n", attrs.isRegularFile());
      System.out.printf("isSymbolicLink: %b%n", attrs.isSymbolicLink());
      System.out.printf("lastAccessTime: %s%n", attrs.lastAccessTime());
      System.out.printf("lastModifiedTime: %s%n", attrs.lastModifiedTime());
      System.out.printf("size: %d%n", attrs.size());
      System.out.println();

      Map<String, Object> attrMap = new TreeMap<>(Files.readAttributes(path, 
                                                                       "*"));
      for (Map.Entry<String, Object> entry: attrMap.entrySet())
         System.out.printf("%s: %s%n", entry.getKey(), entry.getValue());
   }
}

In Listing 8, I pass "*" as the second argument to the second readAttributes() method call to indicate that all attributes for the basic attribute view are to be returned -- not specifying a view name results in basic as the default name. Also, I pass the second readAttributes() method call's returned map to the java.util.TreeMap constructor to obtain a sorted map, so that entries will be output in sorted order.

Compile Listing 8 and run the application. For example, I observe the following output from java PathAttrib PathAttrib.java:

Basic Attributes for PathAttrib.java...

creationTime: 2015-03-18T20:20:43.635406Z
fileKey: null
isDirectory: false
isOther: false
isRegularFile: true
isSymbolicLink: false
lastAccessTime: 2015-03-18T20:20:43.635406Z
lastModifiedTime: 2015-03-18T20:35:20.446953Z
size: 1618

creationTime: 2015-03-18T20:20:43.635406Z
fileKey: null
isDirectory: false
isOther: false
isRegularFile: true
isSymbolicLink: false
lastAccessTime: 2015-03-18T20:20:43.635406Z
lastModifiedTime: 2015-03-18T20:35:20.446953Z
size: 1618

More attribute operations

Q: What other kinds of attribute operations can I perform on a Path object?

A: You can read the attribute values for the file store (a storage pool, device, partition, volume, concrete file system or other implementation-specific means of file storage) that's associated with a Path object. Accomplish this task as follows:

  1. Invoke Files's FileStore getFileStore(Path path) method to obtain the file store.
  2. Invoke java.nio.file.FileStore's Object getAttribute(String attribute) method to return the value for the given file store attribute. You must adhere to the view-name:attribute-name syntax for attribute's string.

Listing 9 presents the source code to a small application that shows you how to use getAttribute() to obtain the values for the NTFS file store implementation's attributes, which are then output.

Listing 9. PathAttrib.java (version 4)

import java.io.IOException;

import java.nio.file.Files;
import java.nio.file.FileStore;
import java.nio.file.Path;
import java.nio.file.Paths;

public class PathAttrib
{
   public static void main(String[] args) throws IOException
   {
      if (args.length != 1)
      {
         System.err.println("usage: java PathAttrib path-object");
         return;
      }

      Path path = Paths.get(args[0]);
      FileStore fs = Files.getFileStore(path);
      if (fs.type().equals("NTFS"))
      {
         String[] attrNames = 
         {
            "totalSpace",
            "usableSpace",
            "unallocatedSpace",
            "volume:vsn",
            "volume:isRemovable",
            "volume:isCdrom"
         };
         for (String attrName: attrNames)
            System.out.println(fs.getAttribute(attrName));
      }
   }
}

When FileStore's String type() method returns NTFS as the file store type, the underlying file store implementation recognizes the attributes identified in the listing. (Instead of obtaining the total space, usable space, and unallocated space via getAttribute() calls, you should use the more convenient long getTotalSpace(), long getUsableSpace(), and long getUnallocatedSpace() methods.)

Compile Listing 9 and run the application. For example, I observe the following output from java PathAttrib PathAttrib.java -- nothing would output when NTFS isn't the file store type:

499808989184
229907410944
229907410944
1079402743
false
false

FileStore also declares a <V extends FileStoreAttributeView> V getFileStoreAttributeView(Class<V> type) method for obtaining a FileStoreAttributeView (an attribute view that's a read-only or updatable view of a file store's attributes) of the given type. Because there are no official subinterfaces for FileStoreAttributeView, this method is probably only useful for custom file stores and API packages.

What's next?

In Part 3, I wrap up this series by presenting more advanced recipes for copying directory hierarchies, finding files, and watching directories for changes. You'll learn about file visitors, globs, and watch services.

download
Get the source code for this post's applications. Created by Jeff Friesen for JavaWorld

The following software was used to develop the post's code:

  • 64-bit JDK 7u6

The post's code was tested on the following platform(s):

  • JVM on 64-bit Windows 7 SP1
1 2 3 Page 3
Page 3 of 3