brief introduction JAVA new I/O (NIO)
Reference document: Getting started with new I/O (NIO)
Preface:
NIO was introduced with JDK1.4 for high speed, block oriented I/O in standard Java code. By defining classes to hold data, and by processing that data in blocks, NIO takes advantage of low-level optimizaitons compared to I/O package could not, without using native libraries.
We will cover most aspect of the NIO library, from high level conceptual stuff to under-the-hood programming detail. To learning about crucial I/O elements like buffers and channels, we will also see how standard I/O elements works in the updated library. You'll also learn about things you can only do with NIO, such as asynchronous I/O and direct buffers.
Input/output: A conceptual overview
I/O in Java programming, I/O has until recently been carried out using a stream metaphor. All I/O is viewed as the movement of single bytes, one at a time, through an object called a stream. Stream I/O is used for contacting the outside world, and it can also used internally for turning objects into bytes and then back into objects.
NIO plays the same role as original I/O, but it uses a different metaphor -- block I/O. As you can see the Java NIO Buffers, the block I/O is more efficient than stream I/O.
Why NIO?
NIO was created allow Java program to implement high-speed I/O without having to write custom native code. NIO moves the most time-consuming I/O activities(namely, filling and draining buffers) back into the OS, thus allowing great increase in speed.
Streams vs blocks
The most important distinction between the original I/O library and NIO has to do with how data is packaged and transmitted. The original I/O deals with data in streams, whereas NIO do with data in blocks.
A stream-oriented I/O system deals with data one byte at a time. An input stream produces one byte of data, and an output stream consumes one byte of data. It's very easy to create filters for stream data , also relatively simply to chain several filters together so that each one does its part in what amounts to single sophisticated processing mechanism. On the flip side, stream-oriented I/O is often rather slow.
Integrated I/O
The original I/O package and NIO have been well integrated in JDK 1.4 java.io.* has been reimplemented using NIO as its base , so it can now take advantage of some features of NIO. For example some java some of classes in the java.io.* package contain methods to read and write data in blocks, which leads to faster processing.
Channel and buffers
Channels and buffers are the central
objects in NIO, and are used for just about every I/O operation.
Channels are analogous to stream in the original IO package. All data
that goes anywhere must pass through a Channel object. A buffer is
essentially a container object. All data that is sent to a channel
must first be placed in a buffer. So any data that is read from a
channel is read into buffer.
What
is a buffer?
A buffer is an object, which is essentially an array. It's an
array of bytes, but other kinds of arrays can be used. But a buffer
is more than just an array. A buffer provides structured access to
data and also keeps track of the system's read/write processes.
In the NIO library, all data is handled with buffers. When data is
read, it's read directly into a buffer, when data is written, it's
written into a buffer. Anytime you access data in NIO, you are
pulling it out of the buffer. A buffer is essentially an array.
What 's a channel ?
A channel is an object from which you can
read data and to which you can write data.Comparing NIO with original
I/O, a channel is like a stream.
Kinds of Channel
Channels differ from stream in that they are bi-directional.
Whereas streams only go in one direction (a stream must be a subclass
of either InputStream or OutputStream), a channel can be opened for
reading, for writing, or for both.
Because they are bi-directional, channels better reflect the
reality of the underlying OS than streams do. In the UNIX model in
particular, the underlying OS channels are bi-directional.
Practice: Reading and
writing in NIO
Reading from a channel is simple: we create a buffer and then ask
a channel to read data into it. Writing data we just create a buffer,
fill it will data, and then ask a channel to write from it.
Reading from a file
For our first exercise, we'll read some data from a file. If we
are using original IO, we will simply create a FileInputStream and
read from that.
In NIO, however, things work a little differently; we first get Channel object from the FileInputStream, and then use that channel to read the data.
Any time you perform a read operation in an NIO system.you are reading from a channel, but you don’t read directly from a channel. Since the data ultimate resides in the buffer, you read from a channel to a buffer.
So reading from a file involves three steps:
- getting the Channel from FileInputStream;
- creating the Buffer
- reading from the Channel into the buffer
Three easy steps:
Our first step is to get a channel. We get the channel from the FileInputStream.
FileInputStream fin = new FileInputStream("DirectMem.java");
FileChannel fc = fin.getChannel();
The next step is to create a buffer and read from the channel into the buffer, as shown here:
ByteBuffer buffer = ByteBuffer.allocate(1024);
fc.read(buffer);
We don't need to tell the channel how much to read into buffer. Each buffer has ssophisticated internal accounting system that keeps track of how much data has been read and how much room there is for more data. We will discuss the Buffer internals overview then.
Writing to a file
Writing is similiar to reading from a file. Here is the sample code:
private static void readingWritingFromFile() throws IOException{
String fileName = "DirectMem.java";
FileInputStream fin = new FileInputStream(fileName);
FileChannel fc = fin.getChannel(); int bufLen = 2<<10;
ByteBuffer buffer = ByteBuffer.allocate(bufLen);
fc.read(buffer); String newFileName = "newDirectMem.txt";
FileOutputStream fout = new FileOutputStream(newFileName);
FileChannel writeFc = fout.getChannel(); ByteBuffer newBuf = ByteBuffer.allocate(bufLen);
String message = "test writing to channel from buffer";
byte[] mesArray = message.getBytes();
for (int i = 0; i < mesArray.length; i++) {
newBuf.put(mesArray[i]);
}
newBuf.flip();
writeFc.write(newBuf); }
Other reading and writing operation please see Reading and Writing with Java NIO
There some examples we combine reads data into the buffer from the input channel, fcin, and the second line writes the data to the output channel, fcout. Notice that before reading into a buffer from the input channel we call the method clear(), and before write newly read data into another channel we call the flip() method prepare the buffer.
Buffer internals
In this section, we will see 2 components of buffers in NIO: state variables and accessor methods.
State variables are key to the "internal accouting system" mentioned in the previous section. With each read/write operation, the internal states changes. By recording and tracking those changes, a buffer is can manage it's own resources.
A buffer has many states, in some cases write data directly into another channel, but often you'll want to look at the data itself. This is acopmlished using the accessor method get(), while if if you want to put raw data in a buffer, you use the accessor method put().
State variables
3 values can be used to specify the state of a buffer:
- position
- limit
- capacity
these variables track the state of the buffer and the data is contains. We'll examine each one in detail, and also see how to fit read/write process. For the sake of the example, we'll assume that we are copying data from an input channel to an output channel.
Position
You will recall that a buffer is really just a glorified array when you read from a channel, position records how much data you have written. It specifies into where is array element the next byte. If you write to a channel, postion will record how much data read from the buffer. It refers to the next eelement you want to read.
Limit
The limit variable specifies how much data there is left to get, or how much room left to put data into.
Capacity
The capacity of a buffer sepcifies the maximum amount of data that can be stored therein. It specifies the size of underlyging array.
The limit is smaller than capacity.
We create buffer as example, let's assume that our buffer capacity is 8 bytes, and the buffer states is shown:
React operations
The limit can not be larger than the ccapacity, and in this case both values are set to 8. We show this by pointing them off the end of the array. The position is set to 0, when read data into the buffer, then the next byte read will be put into slot0; If we write from the buffer, the next byte taken from the buffer will be taken from slot 0.
React operations
When we read data into the buffer, increase the position. In this example we read 5 bytes so add 5 to pposition.
After read byte into buffer from channel, we want write bytes from buffer to channel. But before change ooperation to buffer, we should first call the flip() function. It resets position to 0, and set limit to the position old value.
React operations
You can see the posiiton set to 0 and limit set to 5(Meaning all data we read from buffer just now), Then we begin write bytes from the buffer to channel. And we read 5 bytes from the buffer, add 5 to position and now you can see position is equal to limit.
When all read and write operations finished, we call clear() method to clear all variables:
1. reset positon to 0.
2. limit set to capacity
Conclusion
If you want manipulate data in disk you should firstly read it into buffer from the channel, or if you want to store data back to disk you should write channel from the buffer.
For more detail about manipulation about buffer, please see Java NIO read/write file through FileChannel
brief introduction JAVA new I/O (NIO)的更多相关文章
- Java I/O and NIO [reproduced]
Java I/O and NIO.2---Five ways to maximize Java NIO and NIO.2---Build more responsive Java applicati ...
- Java网络编程和NIO详解开篇:Java网络编程基础
Java网络编程和NIO详解开篇:Java网络编程基础 计算机网络编程基础 转自:https://mp.weixin.qq.com/s/XXMz5uAFSsPdg38bth2jAA 我们是幸运的,因为 ...
- Java网络编程和NIO详解8:浅析mmap和Direct Buffer
Java网络编程与NIO详解8:浅析mmap和Direct Buffer 本系列文章首发于我的个人博客:https://h2pl.github.io/ 欢迎阅览我的CSDN专栏:Java网络编程和NI ...
- Java网络编程和NIO详解9:基于NIO的网络编程框架Netty
Java网络编程和NIO详解9:基于NIO的网络编程框架Netty 转自https://sylvanassun.github.io/2017/11/30/2017-11-30-netty_introd ...
- Java网络编程和NIO详解7:浅谈 Linux 中NIO Selector 的实现原理
Java网络编程和NIO详解7:浅谈 Linux 中NIO Selector 的实现原理 转自:https://www.jianshu.com/p/2b71ea919d49 本系列文章首发于我的个人博 ...
- Java网络编程和NIO详解6:Linux epoll实现原理详解
Java网络编程和NIO详解6:Linux epoll实现原理详解 本系列文章首发于我的个人博客:https://h2pl.github.io/ 欢迎阅览我的CSDN专栏:Java网络编程和NIO h ...
- Java网络编程和NIO详解5:Java 非阻塞 IO 和异步 IO
Java网络编程和NIO详解5:Java 非阻塞 IO 和异步 IO Java 非阻塞 IO 和异步 IO 转自https://www.javadoop.com/post/nio-and-aio 本系 ...
- Java网络编程和NIO详解4:浅析NIO包中的Buffer、Channel 和 Selector
Java网络编程与NIO详解4:浅析NIO包中的Buffer.Channel 和 Selector 转自https://www.javadoop.com/post/nio-and-aio 本系列文章首 ...
- Java网络编程和NIO详解2:JAVA NIO一步步构建IO多路复用的请求模型
Java网络编程与NIO详解2:JAVA NIO一步步构建IO多路复用的请求模型 知识点 nio 下 I/O 阻塞与非阻塞实现 SocketChannel 介绍 I/O 多路复用的原理 事件选择器与 ...
随机推荐
- sql server 日期处理datediff
语法: DATEDIFF(datepart,startdate,enddate) datepart 参数可以是下列的值: date-part : year | quarter | month | we ...
- C# 与 VB.NET 对比
C# 与 VB.NET 对比 2008-06-20 15:30 by Anders Cui, 1462 阅读, 3 评论, 收藏, 编辑 Table of Contents 1.0 Int ...
- poj1700--贪心算法
题意:一群人坐船过河,船只有一辆,且一次最多坐两人,时间按慢的算.求最短过河时间? 总共有两种做法可使用: 1.先让最快和次快的过去,让最快的把船开回,再让最慢和次慢的过去,让次快的把船开回.需两个来 ...
- IOS优秀博客
链接地址:http://www.cnblogs.com/keithmoring/p/4155264.html 剑心的博客信息量很大,适合查阅和入门,学习完,你差不多就可以出山了,还有作为复习IOS的一 ...
- CTreeCtrl点击获得选中项
相应TVN_SELCHANGED可以得到选中的项,在相应函数内如下: LPNMTREEVIEW pNMTreeView = reinterpret_cast<LPNMTREEVIEW>(p ...
- Android StrictMode介绍
转:http://www.blueowls.net/android-strictmode%E4%BB%8B%E7%BB%8D/ /** * enables "strict mode" ...
- jira 解决结果配置
jira 的配置比较繁琐,有很多的小细节,使用中出现了各种小问题,总结梳理下 1.解决结果 问题1:编辑了任务后,解决结果变成了已解决 找到编辑任务所对应的界面方案,将解决结果字段从界面配置里移除 问 ...
- 一些CSS命名规则
一些CSS命名规则 头:header 内容:content/containe 尾:footer 导航:nav 侧栏:sidebar 栏目:column 页面外围控制整体布局宽度:wrapper 左右中 ...
- RelativeLayout布局下实现控件平分空间
起源:使用惯LinearLayout的朋友都知道,若想实现对屏幕的等分,只需要设置Layout_weight的值即可. 可是在RelativeLayout布局下实现等分却不是那么容易. 下面就简单介绍 ...
- linux基础--chkconfig 详解
chkconfig命令主要用来更新(启动或停止)和查询系统服务的运行级信息.谨记chkconfig不是立即自动禁止或激活一个服务,它只是简单的改变了符号连接. 使用语法:chkconfig [--ad ...