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 多路复用的原理 事件选择器与 ...
随机推荐
- 漫谈servlet技术
1.要谈到Servlet技术,不得不先谈谈动态网页的概念. 编写过网页的人都知道,浏览器能够根据HTML静态标记语言来显示各式各样的网页.但是如果我们需要在网页上完成一些业务逻辑:比如登陆验证.或者说 ...
- Mantis的附件图片实现预览/弹出层动画效果预览图片(LightBox2)的完美解决方案[Z]
方法1: 在Mantis的配置文件中,加入此句,将这个值设的很大,就可以直接看到图片 1 $g_preview_attachments_inline_max_size=1000000; 效果如图 这个 ...
- DOM缘起
DOM是现在按W3C标准的浏览器均实现的标准.HTML.CSS.DOM共同在结构.表现.交互上共同支撑起一个页面.当然,必须以用户为中心.平稳退化.逐渐增强.DOM的操作是通过JS来实现的.JS最初在 ...
- EC读书笔记系列之10:条款16、17
条款18 让接口容易被正确使用,不易被误用 记住: ★“促进正确使用”的办法包括接口的一致性,以及与内置类型的行为兼容 ★“阻止误用”的办法包括建立新类型.限制类型上的操作,束缚对象值,以及消除客户的 ...
- std::string 字符替换函数
// 替换路径中所有“\”为“/” #include <algorithm> static std::string ConvertSlash(std::string& strUrl ...
- centos安装中文支持(转)
安装中文支持包. yum install fonts-chineseyum install fonts-ISO8859-2 -------- 一.安装中文支持方法1.在安装光盘中找到一下包进行安装.r ...
- mysql学习(四)-字段类型
mysql数据类型: 数值型: 整形:int 浮点型:float double decimal:定点型 日期: date '2012-01-02' time '10:01:01' datetime ...
- Linux简介(好!)
Linux操作系统介绍 来源:233网校论文中心[ 2009-12-02 14:23:00 ]阅读:1作者:王长青编辑:studa20 [摘 要]文章从Unix.Minix系统的产生引出了Linux操 ...
- struts2笔记01-环境搭建
1.官网下载struts2 struts-2.3.28-all.zip,这个包可谓应有尽有,以后全靠它了! 2.jar包怎么选? (1)struts-2.3.28-all\struts-2 ...
- [转]struct 用法深入探索
struct用法深入探索 作者: Cloudward 1. struct的巨大作用 面对一个人的大型C/C++程序时,只看其对struct的使用情况我们就可以对其编写者的编程经验进行评估.因为一个大型 ...