File Attributes int the NIO.2 API

Introduction

With NIO.2 we can easily determine the attributes of a file by using the java.nio.file.attribute package.

Various file systems have different properties associated with files but NIO.2 groups the attributes into views, each view is specific to a particular file system implementation.

NIO.2 comes with a set of views:

  • BasicFileAttributeView: This view contains a set of common attributes supported by all filesystem implementations. The inner name of the attribute view is ‘basic’.
  • DosFileAttributeView: This view contains a set of attributes specific to filesystems that implement DOS attributes. The inner name of the attribute view is ‘dos’.
  • PosixFileAttributeView: This view contains a set of attributes specific to file systems that support the POSIX standards. The inner name of the attribute view is ‘posix’.
  • AclFileAttributeView: This view is supported by all filesystems implementations that have the concept of ACL. The inner name of the attribute is ‘acl’.
  • FileOwnerAttributeView: This view is supported by all filesystems implementations that have the concept of “ownership” over a file. The inner name of the attribute is ‘owner’.
  • UserDefinedFileAttributeView

How do we determine what are the views supported by our filesystem ?

Output (I am using a Windows 7 machine):

Everytime we want to access the view attributes of a file/folder, it is advisable to check if the file system supports the particular view. NIO.2 allows us to test this using the FileSystem.supportedFileAttributeViews() method .

Eg.:

Output:


Supported file attributes

Every view support file attributes.

BasicFileAttributeView

Attribute Returned Type Comments
“basic:creationTime” FileTime The exact time when the file was created.
“basic:fileKey” Object An object that uniquely identifies a file or null if a file key is not available.
“basic:isDirectory” Boolean Returns true if the file is a directory.
“basic:isRegularFile” Boolean Returns true if a file is not a directory.
“basic:isSymbolicLink” Boolean Returns true if the file is considered to be a symbolic link.
“basic:isOther” Boolean
“basic:lastAccessTime” FileTime The last time when the file was accesed.
“basic:lastModifiedTime” FileTime The time when the file was last modified.
“basic:size” Long The file size.

DosFileAttributeView

Attribute Returned Type Comments
“dos:archive” Boolean Return true if a file is archive or not.
“dos:hidden” Boolean Returns true if the file/folder is hidden.
“dos:readonly” Boolean Returns true if the file/folder is read-only.
“dos:system” Boolean Returns true if the file/folder is system file.

PosixFileAttributeView

Attribute Returned Type Comments
“posix:permissions” Set<PosixFilePermission> The file permissions.
“posix:group” GroupPrincipal Used to determine access rights to objects in a file system

AclFileAttributeView

Attribute Returned Type
“acl:acl” List<AclEntry>
“acl:owner” UserPrincipal

Retrieving file/folder attributes

There are two ways to extract those attributes:

  • Getting a bulk of attributes using readAttributes() method ;
  • Getting single attributes using getAttribute() method .

Retrieving bulk attributes:

Output:

We can also retrieve single attributes. Example:


Updating file/folder attributes

The simplest way to update file attributes is by using the Files.setAttribute method.
In the following example we are going to modify the creation time of a given file:

Output:


Getting attributes of FileStores

To determine the default FileStore object we can invoke FileSystems.getDefault(), but it’s also possible to obtain the list of FileStores by iterating over the list we obtain calling FileSystem.getFileStores() .

Each file store object has dedicated methods for obtaining the name, type, totalSpace etc.

Output:

The NIO.2 Path Class

The Path class is considered to be the entry point for exploring the NIO.2 API. Basically every I/O operation in NIO.2 will exploit the facilities offered by this class.

Path is basically an upgraded version of the java.io.File class.

1. Getting the Path of the Home Directory When you want to obtain the path that points to a specific file in the Home directory, you can proceed as shown. The returned home directory is dependent on each operating system:


2. Obtaining information about the Path: Path Root and Path Parent 


3. Splitting a path in its name elements This is a nice feature that allows the programmer to split the path in it’s forming elements. For example if a file has the following path: ‘C:\Users\andreinc\Downloads\file1.txt’ the following function will retrieve the forming elements of the path, a List containing the following elements: [‘C:\’, ‘Users’, ‘andreinc’, ‘Downloads’, ‘file1.txt’] .

And the output is:


4. Getting the subpath We can extract a relative path using a subpath method. This method accept two parameters, the start (index) and end (index) in the subsequence of elements.

And the output is:


5. Combining two paths
This allows you to define a fixed root path and append to it partial paths.

Output:


6. Comparing two paths
Two paths can be compared as objects, using the “equals()” function. This method is related to the “equals()” method of class Object, thus the compared paths are not required to exist, and this method does not check if the paths are the same file.

But sometimes we want to check if two Path objects represent the same file / folder . In this case we will need to use java.nio.File.Files.isSameFile() method.

Eg.:

Output:

The Path class implements the Comparable interface, thus we can compare two paths by using the compareTo() method . The comparation will be lexicographical, so this will be useful for “sorting”.


7. Iterating over the elements of a Path

The Path class implements the Iterable interface, so we can use a foreach to iterate over the elements of a Path.

Eg.:

Output:

HR Schema for MySQL and Maria DB

If you are familiar with Oracle’s HR schema you may find the following useful.

I’ve written a script that generates a similar sample schema for MySQL and MariaDB. The table structure and data remains the same.

Database Diagram (this file was generated using MySQL Workbench):

hr_mysql

 

The SQL script can be found here

To clone the GitHub project:

Getting started with Apache Maven and Eclipse

Apache Maven is a popular build automation tool, for large Java Projects.

All major Java IDEs (IntelliJ IDEA, Eclipse and Netbeans) fully support Maven integration, by default or via plugins.

In order to get started with Maven you will need to:

1. Download Apache Maven from the original site, which is: http://maven.apache.org/ . Check for the Download section:

Image 1

2. Extract the .zip file in your desired location (Eg. D:javatoolsapache-maven-3.1.0 )

Image 23. The next step will be to setup the following system variables M2, M2_HOME, JAVA_HOME and also add the Maven bin directory to System Path. For managing the System Variables on my station I am using a dedicated software called Rapid Environment Editor:

Image 3

 

If you don’t want to install Rapid Environment Editor, you can use the Windows built-in feature to edit System Variables: Control Panel -> System and Security -> System -> Advanced System Settings -> Advanced / Environment Variables .

Image 4

 

4. Modify the location of Maven repository – this is the location where Maven installs all its artifacts (jars, etc.) . By default the location for this folder is ${user.home}/.m2/repository . On Windows machines this may raise issues, as most users keep their C: partition small enough and dedicated only for their Operation System. In order to modify this behavior edit %M2_HOME%\\confsettings.xml . In my case this location is D:\\java\\tools\\apache-maven-3.1.0\\conf\\settings.xml. The property you need to modify is called: localRepository :

Image 5

 

In my case the new value for this property is: D:\\java\\tools\\apache-maven-3.1.0-repo .

5. The next step will be to test if maven was successfully installed. Open up a Command Prompt and type:

If you’ve followed all the above mentioned steps the output should look like:

Image 6

 

6. One of the cool features of Maven are the so-called Archetypes . Those are project structure / architecture templates that can save you a lot of time when you are defining boilerplate-like code. Right now Maven offers am impressive list of archetypes for defining all kinds of projects: JDBC Projects, Spring Projects etc. But in this tutorial we will use this feature in order to create a simple Java Project that are we going to import later into Eclipse. 

In order to create a simple project use this command:

  • groupId is be the package name ;
  • artifactId is the name of the project ;
  • archetypeArtifactId is the type of the archetype (in our case a simple Java Project).

If everything was successful (after some downloads in your repository) you will probably see something similar to :

Image 7

 

If you analyze your folder structure you will see something like this:

Image 2

 

7. The last step will be to generate the necessary descriptors for Eclipse so that our newly generated project skeleton will be recognized as an Eclipse project. In the project root folder:

Image 3

 

 

8. The next step will be to import the project into Eclipse (File -> Import -> Existing Projects into Workspace):

Image 4

 

 

And everything is done.

Adding custom annotations to your java beans

Java annotations are syntactic meta-information that can be added to your Java source code. You can annotate classes, methods, variables, method parameters and even packages.

The great advantage of Java annotations over javadoc tags is that those bits of information can be reflective and thus they can be made available to the VM at runtime (using the the Java Relection API).

Other than this, modern Java frameworks (like Spring) make heavy use of annotations in order to let the developer, extend, inject data and configure existent behaviors.

In this article we will define our own custom annotations, and we will use reflection to analyze and enhance the behavior of our Java beans at run-time.

Let’s suppose we want to write a mechanism that transforms (let’s say serialize) a given collection of java beans instances to a CSV file .CSV stands for Comma Separated Values. If you want to learn more about CSV files please check out this wikipedia article.

We don’t want to “serialize” all the fields, so will use annotations to mark only the fields we wish to “export”.

The first step will be the write the annotations class. We will call this one CSVExport.java :

As you can see all annotations related classes are included in the java.lang.annotation.* package. Other than this we will need to mark this annotation with a RetentionPolicy that will make it available at run-time, and we will specify that the annotation can only be used in conjunction with class methods (in our case those methods will be the bean getters).

At this point we will write a “model” java bean and we will mark the getters we want to serialize with our newly defined custom annotation.

Only the method that were annotated with @CSVExport will be serialized to the resulting file. If no annotations is present the specified getter method will be ignored.

The next step will be to write the class that actual export our collection. We will call this one CollectionToCSV.java:

The most important method buildCSVRow , as it iterates through the methods of the T.class (where T appears as a generic type, but in our case will be a TestModel instance), checks if the getter is marked with the @CSVExport annotation, and if the answer is yes the method will be invoked and the result will be included in our serialization.

If we run the main method the result will be:

If in the TestModel class we remove all the getters annotations nothing will be exported.