io和nio的区别
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了io和nio的区别相关的知识,希望对你有一定的参考价值。
什么是通道Channel(通道)顾名思义,就是通向什么的道路,为某个提供了渠道。在传统IO中,我们要读取一个文件中的内容,通常是像下面这样读取的:
public static void copy_1(){
FileInputStream in = null;
FileOutputStream out = null;
try {
in = new FileInputStream("c:\timg.jpg");
out = new FileOutputStream("D:\timg.jpg");
int ch = 0;
while((ch=in.read())!=-1){//这个方法是对这个流一个一个字节的读,返回的int就是这个字节的int表示方式
out.write(ch);
}
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
if(out!=null){
out.close();
}
} catch (IOException e) {
e.printStackTrace();
}
try {
if(in!=null){
in.close();
}
} catch (Exception e2) {
e2.printStackTrace();
}
}
}
public static void copy_2(){
FileInputStream in = null;
FileOutputStream out = null;
try {
in=new FileInputStream("c:\timg.jpg");
out=new FileOutputStream("d:\timg.jpg");
byte[] buffer = new byte[1024];
int len = 0;
while((len=in.read(buffer))!=-1){//这个方法是先规定一个数组长度,将这个流中的字节缓冲到数组b中,返回的这个数组中的字节个数,这个缓冲区没有满的话,则返回真实的字节个数,到未尾时都返回-1
out.write(buffer, 0, len);
}
} catch (Exception e) {
e.printStackTrace();
}finally {
try {
if(out!=null){
out.close();
}
} catch (IOException e) {
e.printStackTrace();
}
try {
if(in!=null){
in.close();
}
} catch (Exception e2) {
e2.printStackTrace();
}
}
}
这里的InputStream实际上就是为读取文件提供一个通道的。
因此可以将NIO 中的Channel同传统IO中的Stream来类比,但是要注意,传统IO中,Stream是单向的,比如InputStream只能进行读取操作,OutputStream只能进行写操作。而Channel是双向的,既可用来进行读操作,又可用来进行写操作。
以下是常用的几种通道:
FileChannel
SocketChanel
ServerSocketChannel
DatagramChannel
通过使用FileChannel可以从文件读或者向文件写入数据;通过SocketChannel,以TCP来向网络连接的两端读写数据;通过ServerSocketChanel能够监听客户端发起的TCP连接,并为每个TCP连接创建一个新的SocketChannel来进行数据读写;通过DatagramChannel,以UDP协议来向网络连接的两端读写数据。
public class Test {
public static void main(String[] args) throws IOException {
File file = new File("data.txt");
FileOutputStream outputStream = new FileOutputStream(file);
FileChannel channel = outputStream.getChannel();
ByteBuffer buffer = ByteBuffer.allocate(1024);
String string = "java nio";
buffer.put(string.getBytes());
buffer.flip(); //此处必须要调用buffer的flip方法
channel.write(buffer);
channel.close();
outputStream.close();
}
}
通过上面的程序会向工程目录下的data.txt文件写入字符串"java nio",注意在调用channel的write方法之前必须调用buffer的flip方法,否则无法正确写入内容
什么是缓冲区Buffer(缓冲区)
Buffer,故名思意,缓冲区,实际上是一个容器,是一个连续数组。Channel提供从文件、网络读取数据的渠道,但是读取或写入的数据都必须经由Buffer。
在NIO中,Buffer是一个顶层父类,它是一个抽象类,常用的Buffer的子类有:
ByteBuffer
IntBuffer
CharBuffer
LongBuffer
DoubleBuffer
FloatBuffer
ShortBuffer
如果是对于文件读写,上面几种Buffer都可能会用到。但是对于网络读写来说,用的最多的是ByteBuffer
什么是选择器Selector(选择器)
Selector运行单线程处理多个Channel,如果你的应用打开了多个通道,但每个连接的流量都很低,使用Selector就会很方便。例如在一个聊天服务器中。要使用Selector, 得向Selector注册Channel,然后调用它的select()方法。这个方法会一直阻塞到某个注册的通道有事件就绪。一旦这个方法返回,线程就可以处理这些事件,事件的例子有如新的连接进来、数据接收等。
io和nio的区别
IO是面向流的,NIO是面向缓冲的;
IO是阻塞的,NIO是非阻塞的;
IO是单线程的,NIO 是通过选择器来模拟多线程的;
以上是关于io和nio的区别的主要内容,如果未能解决你的问题,请参考以下文章