Java NIO.2是一个基于通道,缓冲器导向的技术,以处理输入/输出操作。其是在Java中基于输入/输出系统的一个常规流互补的延伸。 然而,该方法是不同的,也许是把它放在叫做java.nio的一个单独的包中,而不是在intojava.io的原因。 本文探讨了一些在NIO介绍的代码示例中新的输入/输出API的关键环节。
在Java的标准输入/输出系统中
低电平的输入/输出操作是一个复杂的过程,除非小心处理,否则可以拖垮性能。 java.io包提供标准API,以通过流对象处理系统的输入/输出。 对于流,我们指的是数据的一个序列,其可能被视为位序列。标准Java输入/输出支持序列和读取各种数据类型,如字节,原始类型或对象往复运动改变端点设备。正是这些流被转换成所需要的对象和Java类型。指定的抽象类,InputStream和OutputStream,包括消费,并通过它的许多方法和子类产生的数据流的手段。 所提供的API是比较高的水平,这虽然灵活,但也可能会产生性能瓶颈。NIO.2给出处理的一个新的层面,强调性能,现有系统的补充的输入/输出。
package org.mano.example;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class StandardFileHandling {
public static void main(String[] args) {
BufferedReader reader = null;
try {
reader = new BufferedReader(new
FileReader("testfile.txt"));
String str;
do {
str = reader.readLine();
System.out.println(str);
} while (str != null);
} catch (IOException ex1) {
System.out.println("IO Error " +
ex1.getMessage());
} finally {
try {
if (reader != null)
reader.close();
} catch (IOException ex2) {
System.out.println("IO Error " +
ex2.getMessage());
}
}
}
}
在Java的新输入/输出系统中
NIO.2的创建,同时考虑性能,而无需求助于原生代码。然而,这并不意味着基于数据流的输入/输出效率不高。但是,有些场合NIO.2能表现的更好。例如,以下是一些选择NIO.2而不是传统的输入/输出的原因。
? NIO.2代表一些费时的问题,例如输入/输出缓冲到底层操作系统的问题。 这样可以提高性能。
? NIO.2使用数据流而不是java.io的顺序流式传输块为导向的方法。
? 顺序流式传输是极好的链式过滤,但不利于缓存的数据操作。
? NIO.2处理的数据块;这些块被产生并通过缓冲器消耗。 作为结果,来回移动缓冲的中数据对于处理过程有更大的灵活性。
? 由于NIO.2流是基于信道的,一个单线程可以管理多个线程。
? 阻止NIO.2流不利于分析。 传统的输入/输出是比较简单及高效的,因为它是顺序比特传输方式。
NIO.2缓冲区和通道概述
我们知道,NIO.2是缓冲区为导向及以渠道为主;这两个功能是它的基本组成部分。 缓冲区是保存数据的存储器,而信道是通过其打开的连接发送的数据,如文件或套接口介质。
所有的缓冲区类,如ByteBuffer,CharBuffer等等,都在java.nio包中定义的abstractBuffer类的子类。 缓冲区可以被视为Java元素的数组受限于它的内容的数量包含。 被缓冲器所引用的当前索引表示下一个读/写元件。 当前索引相对每个读/写操作前移。
信道定义用于输入/输出操作的开放连接的端点。 它被定义于thejava.nio.channels包中。 它可以被看作是一个连接管与在源和目标的开口端。 该信道类实现通道接口,其扩展了AutoCloseable 及Closeable接口。 由于其的AutoCloseable扩展,我们可以使用带有一个资源块的try,并且当不再需要该信道时,其会被自动关闭。
package org.mano.example;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.SeekableByteChannel;
import java.nio.file.Files;
import java.nio.file.InvalidPathException;
import java.nio.file.Path;
import java.nio.file.Paths;
public class NIOFileHandling {
public static void main(String[] args) {
Path filePath = null;
try {
filePath = Paths.get("testfile.txt");
} catch (InvalidPathException ex1) {
System.out.println("Path Error " + ex1);
return;
}
try (SeekableByteChannel channel =
Files.newByteChannel(filePath)) {
ByteBuffer buff = ByteBuffer.allocate(10);
while (channel.read(buff) > 0) {
buff.flip();
for (int i = 0; i < buff.limit(); i++) {
System.out.print((char) buff.get());
}
buff.clear();
}
System.out.println();
} catch (IOException ex) {
System.out.println("I/O error " + ex);
}
}
}
字符集和选择器
字符集与经由信道倒入及倒出的原始数据字节一起工作。 通过定义映射字节的方式至字符,它实际上根据读/写操作对数据进行编码及解码。 编码是指将字符序列转换为字节,而解码是指转换字节序列为字符。 我们不经常使用字符集,因为默认的编码器和解码器已提供。 但是,如果有需要,我们自己就可以很容易覆盖默认的编码器和解码器。 字符集,编码器和解码器由thejava.nio.charset包中提供的类进行支持。
选择器是有点棘手,其有许多涉及的概念,如同步/异步I / O。其需要单独的一篇文章,并会简单地超出探索这个概念的范围。在非常基本的水平,如果它已准备好执行输入/输出操作的服务,它提供了我们能够使用的信道。例如,我们可以查询信道对象,如果有准备读取任何字节或已准备好接受任何传入的连接,等等。 选择器通过在java.nio.channels包中定义的类支持,最适用于套接口的支持渠道。
路径接口
JDK7的改进NIO.2包括三个新的包:java.nio.file,java.nio.file.attribute,andjava.nio.file.attribute。除了这些,或许最重要的是路径接口。 路径现在包括一个通过目录结构描述文件位置的路径。 它也提供了结合许多NIO.2文件属性的特征,如getName(int index)方法。 该方法返回一个包含了位置参数为指标的路径名元素的路径对象。零值表示该元件是最接近所提供绝对路径的根。 该方法getNameCount()返回在路径中的元素名称个数。 观察下面的代码片段。
路径对象的创建:
路径filePath = Paths.get("/home/mano/testfile.txt");
这将打印home 作为根元素:
System.out.println("Root is :"
+filePath.getName(0).toString());
其将打印mano,在索引1之后的下一个name元素内:
System.out.println("name element next to root :"
+filePath.getName(1).toString());
其将打印路径中的name元素的个数;例如3:
System.out.println("Total name elements in the path :"
+filePath.getNameCount());
结论
在Java的标准输入/输出系统中
低电平的输入/输出操作是一个复杂的过程,除非小心处理,否则可以拖垮性能。 java.io包提供标准API,以通过流对象处理系统的输入/输出。 对于流,我们指的是数据的一个序列,其可能被视为位序列。标准Java输入/输出支持序列和读取各种数据类型,如字节,原始类型或对象往复运动改变端点设备。正是这些流被转换成所需要的对象和Java类型。指定的抽象类,InputStream和OutputStream,包括消费,并通过它的许多方法和子类产生的数据流的手段。 所提供的API是比较高的水平,这虽然灵活,但也可能会产生性能瓶颈。NIO.2给出处理的一个新的层面,强调性能,现有系统的补充的输入/输出。
package org.mano.example;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class StandardFileHandling {
public static void main(String[] args) {
BufferedReader reader = null;
try {
reader = new BufferedReader(new
FileReader("testfile.txt"));
String str;
do {
str = reader.readLine();
System.out.println(str);
} while (str != null);
} catch (IOException ex1) {
System.out.println("IO Error " +
ex1.getMessage());
} finally {
try {
if (reader != null)
reader.close();
} catch (IOException ex2) {
System.out.println("IO Error " +
ex2.getMessage());
}
}
}
}
在Java的新输入/输出系统中
NIO.2的创建,同时考虑性能,而无需求助于原生代码。然而,这并不意味着基于数据流的输入/输出效率不高。但是,有些场合NIO.2能表现的更好。例如,以下是一些选择NIO.2而不是传统的输入/输出的原因。
? NIO.2代表一些费时的问题,例如输入/输出缓冲到底层操作系统的问题。 这样可以提高性能。
? NIO.2使用数据流而不是java.io的顺序流式传输块为导向的方法。
? 顺序流式传输是极好的链式过滤,但不利于缓存的数据操作。
? NIO.2处理的数据块;这些块被产生并通过缓冲器消耗。 作为结果,来回移动缓冲的中数据对于处理过程有更大的灵活性。
? 由于NIO.2流是基于信道的,一个单线程可以管理多个线程。
? 阻止NIO.2流不利于分析。 传统的输入/输出是比较简单及高效的,因为它是顺序比特传输方式。
NIO.2缓冲区和通道概述
我们知道,NIO.2是缓冲区为导向及以渠道为主;这两个功能是它的基本组成部分。 缓冲区是保存数据的存储器,而信道是通过其打开的连接发送的数据,如文件或套接口介质。
所有的缓冲区类,如ByteBuffer,CharBuffer等等,都在java.nio包中定义的abstractBuffer类的子类。 缓冲区可以被视为Java元素的数组受限于它的内容的数量包含。 被缓冲器所引用的当前索引表示下一个读/写元件。 当前索引相对每个读/写操作前移。
信道定义用于输入/输出操作的开放连接的端点。 它被定义于thejava.nio.channels包中。 它可以被看作是一个连接管与在源和目标的开口端。 该信道类实现通道接口,其扩展了AutoCloseable 及Closeable接口。 由于其的AutoCloseable扩展,我们可以使用带有一个资源块的try,并且当不再需要该信道时,其会被自动关闭。
package org.mano.example;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.SeekableByteChannel;
import java.nio.file.Files;
import java.nio.file.InvalidPathException;
import java.nio.file.Path;
import java.nio.file.Paths;
public class NIOFileHandling {
public static void main(String[] args) {
Path filePath = null;
try {
filePath = Paths.get("testfile.txt");
} catch (InvalidPathException ex1) {
System.out.println("Path Error " + ex1);
return;
}
try (SeekableByteChannel channel =
Files.newByteChannel(filePath)) {
ByteBuffer buff = ByteBuffer.allocate(10);
while (channel.read(buff) > 0) {
buff.flip();
for (int i = 0; i < buff.limit(); i++) {
System.out.print((char) buff.get());
}
buff.clear();
}
System.out.println();
} catch (IOException ex) {
System.out.println("I/O error " + ex);
}
}
}
字符集和选择器
字符集与经由信道倒入及倒出的原始数据字节一起工作。 通过定义映射字节的方式至字符,它实际上根据读/写操作对数据进行编码及解码。 编码是指将字符序列转换为字节,而解码是指转换字节序列为字符。 我们不经常使用字符集,因为默认的编码器和解码器已提供。 但是,如果有需要,我们自己就可以很容易覆盖默认的编码器和解码器。 字符集,编码器和解码器由thejava.nio.charset包中提供的类进行支持。
选择器是有点棘手,其有许多涉及的概念,如同步/异步I / O。其需要单独的一篇文章,并会简单地超出探索这个概念的范围。在非常基本的水平,如果它已准备好执行输入/输出操作的服务,它提供了我们能够使用的信道。例如,我们可以查询信道对象,如果有准备读取任何字节或已准备好接受任何传入的连接,等等。 选择器通过在java.nio.channels包中定义的类支持,最适用于套接口的支持渠道。
路径接口
JDK7的改进NIO.2包括三个新的包:java.nio.file,java.nio.file.attribute,andjava.nio.file.attribute。除了这些,或许最重要的是路径接口。 路径现在包括一个通过目录结构描述文件位置的路径。 它也提供了结合许多NIO.2文件属性的特征,如getName(int index)方法。 该方法返回一个包含了位置参数为指标的路径名元素的路径对象。零值表示该元件是最接近所提供绝对路径的根。 该方法getNameCount()返回在路径中的元素名称个数。 观察下面的代码片段。
路径对象的创建:
路径filePath = Paths.get("/home/mano/testfile.txt");
这将打印home 作为根元素:
System.out.println("Root is :"
+filePath.getName(0).toString());
其将打印mano,在索引1之后的下一个name元素内:
System.out.println("name element next to root :"
+filePath.getName(1).toString());
其将打印路径中的name元素的个数;例如3:
System.out.println("Total name elements in the path :"
+filePath.getNameCount());
结论
NIO.2只是简单地添加新功能至在Java内处理的输入/输出。其也铺平了使用管理线程数多个通道的道路。这需要引导开放连接的多个服务器的应用。另外,其需要通过单一信道处理大量数据,而使用NIO.2应用程序也可能是有利的。
文章来源:http://www.qiqee.net/single?id=111