This, an interesting, file I/O mechanism, introduced in Java 5, brings many important features to provide something very new and to address few, I may not call those as issues, but requirements of File I/O. This is called Java file nio. In this java nio tutorial, we try to explore what all is there as part of this new package by understanding the concepts behind and writing code examples to use the features. It contains many high level APIs that can be used to perform different I/O operations.
In this discussion, we try to get overview of what is nio, what is rational behind introducing different features in this API and few code examples.
Why is It Called nio?
This can be a basic question in any Java nio tutorial. One can say that it includes APIs that can be used to perform non-blocking I/O that is why it is called nio. But actually it is simpler than that. It is just new I/O, hence nio.
What is Exactly Non-Blocking I/O?
Let us understand through this java nio tutorial, what gets blocked when it is blocking I/O. In old file I/O, while performing read or write to a file, the working thread gets blocked until the operation is completed. Means, it does only reading or writing to file and does not execute next statements in program until those operations are done. What is impact of it? First question, what if the program does not wants to wait for file operation to complete, i.e. it can continue doing something else in parallel? Existing I/O does not permit this. Second, file I/O time does not only depend on the Java code performance, but it has to do with the network and underlying OS as well. Then why Java program performance is impacted just because we don’t have feature to do something else?
If the thread can continue executing next statements instead of waiting for completion of the I/O operation started, it is not blocking. Hence it is called non-blocking. Obviously, you must be thinking, how does the file read/write continuation and completion will be handled? It is left to programmer, if we want non-blocking behavior then we also need to ensure completion of the parallel running tasks. May appear complex here, but we can take this with and example in asynchronous file operation below.
How does Non-Blocking I/O Work?
It is an important concept to explain in a java nio tutorial. Very simple to understand, just read non-blocking as parallel for a moment and you will get the clue. If we want to the file operations to run in parallel mode, what is solution in Java? Threads, correct? This is exactly how it works. Another thread is spawn for the file operation and it continues doing the job we initiated, while main thread goes ahead doing next tasks.
We can look at this asynchronous file write call example. Here the main thread continues executing next statement by assigning file write to a new thread. As a developer we have to write a logic that checks if the read/write operation is completed or not. Print statements of this example can give us exact thread details.
What are Contents of nio Package?
Below are the important classes grouped under different categories. These groups are primary based on what is use of these classes from a developer point of view. Actual packages under nio package group these classes differently.
Let us understand these groups and important classes in these groups.
The philosophy behind this grouping is the level of interaction or representation with/of file system. We group the classes from broader level of representation and usage to finer level and helper classes in the end. Time to dive deep into details.
Path and File System Representation
We have a generic class java.nio.Paths, which gives methods that can be used to get representation of a file system object using URI or String path.
Similarly, we have FileSystem and FileSystems classes which are designed to encapsulate underlying file system to represent in some way or other.
Specific Objects
In non-nio APIs, we had used java.io.File class to represent a file or folder. In nio, we use java.nio.file.Path to represent anything that can be called as “path”, it can be a file or a path mapping to directory or file. It is definitely more than just the name change. Path is more powerful than the File class.
It is not independent of the underlying OS. If we want to compare a Path representing a file on Unix with a Path representing a file on Windows, it won’t be a direct comparison. You can be bold to say that this class is not platform independent, and it is correct also, as it is representing something very native to OS, a file/directory/symbolic link.
Another important thing that Path supports now is symbolic links. Path can be used to represent symbolic links.
In addition to this, we have more objects such as Files that provides methods to operate on Path. Also, there are classes to interface underlying OS events. These events are the events occurring on certain Path representation.
File Operation and File Data Operations
To enhance non-blocking I/O support, nio package provides classes that allow access to file data in different asynchronous way.
Channels can represent different (file) data streams or buffers more appropriately. Examples can be FileChannel, AsynchronousFileChannel, AsynchronousSocketChannel etc. These channels can be configured to receive buffered data from underlying sources.
Selectors allow a thread to select a Channel from such registered multiple channels and read/process data provided by such a channel in a non-blocking way.
Just try to visualize that there are multiple sources of data, each source is mapped through an appropriate Channel. Channels are registered to a Selector. A thread can select a desired Channel from Selector and read/write data using this channel to a source/target. Thread does not need to wait until the data is read by the Channel. Instead it can continue doing other work. This is non-blocking I/O, we have discussed it above.
Classes Supporting File Operations
These are basically supporting classes required while performing core operations using nio. If you look at names, and attributes, you can see what is use of those.
Java nio Tutorial Code Examples:
Using these concepts, below are few code examples that can help programmers while writing code using nio package classes.
- Create a File
- Read a File
- Read a File Using FileChannel
- Asynchronous File Writing Using AsynchronousFileChannel
- Using Glob in nio
- Checking if Directory
- Recursive Delete in A Directory
- Monitor or Watch Directory for Changes
How to Write File With Java nio Package?
This post is part of Java nio Tutorial. In this example we are going to see one of the basic steps of file io, how to write file with java nio. Here is a code example of creating a new file using Java’s new IO i.e. nio package. It creates a file and writes one line to the file. We are going to use following nio classes to achieve our goal.
com.nio.charset.Charset – It defines file encoding, we are using UTF-8 character encoding in this example.
com.nio.file.Files – It exposes many static methods required to operate on files, directories, etc. We are going use this class to create a file and create a BufferedWritter to write in this file.
com.nio.file.Path - In simple terms it represents a file object on file system.
com.nio.file.Paths – It exposes static methods to return Path object by taking String and URI format path.
Write file With Java nio:
Here is code to create a file.
SimpleNIOFileWriter.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
|
package net.deepakgaikwad.javanio.examples;
import java.io.BufferedWriter;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
public class SimpleNIOFileWriter {
/**
* @param args
*/
public static void main(String[] args) {
Path file = null;
BufferedWriter bufferedWriter = null;
try{
file = Files.createFile(Paths.get(
"D:\\DeepakGaikwadNet\\Resources\\SimpleNIOData.txt"));
Charset charset = Charset.forName("UTF-8");
String line = "I am writing using NIO.";
bufferedWriter = Files.newBufferedWriter(file, charset);
bufferedWriter.write(line, 0, line.length());
}catch(IOException e){
e.printStackTrace();
}finally{
try{
bufferedWriter.close();
}catch(IOException ioe){
ioe.printStackTrace();
}
}
}
}
|
Along with classes of nio package to get handle of file, we are using Charset class with UTF-8 encoding. This class is used to define encoding of the file in which we want to write the file.
In this example we are focusing on writing to the file, we are not taking care of exceptions properly. You may want to use appropriate exception handling as per requirement.
Ensure the buffer writer is closed after the writing work is done.
In this example we are focusing on writing to the file, we are not taking care of exceptions properly. You may want to use appropriate exception handling as per requirement.
Ensure the buffer writer is closed after the writing work is done.
|
No comments:
Post a Comment