管道(Pipe)
Java NIO 管道是2个线程之间的单向数据连接。Pipe有一个source通道和一个sink通道。数据会被写到sink通道,从source通道读取。
使用方法
(1)创建管道
通过Pipe.open()方法打开管道。
(2)向管道写数据
要向管道写数据,需要访问sink通道。
Pipe.SinkChannel sinkChannel = pipe.sink();
(3)通过调用SinkChannel的write()
方法,将数据写入SinkChannel
(4)从管道读取数据
从读取管道的数据,需要访问source通道
Pipe.SourceChannel sourceChannel = pipe.source();
(5)调用source通道的read()方法来读取数据
(本文出自ochina的博主happyBKs的博文:https://my.oschina.net/happyBKs/blog/edit/1604233)
代码示例
下面的代码其实可以分在两个线程内,通过一个管道,在发送数据的源头线程内获取SinkChannel,将数据写入缓冲区,缓冲区切换成读模式,写入SinkChannel;通过该管道在接收数据的线程内获取SourceChannel,然后从SourceChannel读取数据放到缓冲区,然后切换缓冲区为读模式,将数据取出。
本例中为了说明数据是从管道来的,我将缓冲区在写入SinkChannel之后给清空了。最后从SourceChannel中重新获得。
package com.happybks.nio.nio;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.Pipe;
import java.nio.channels.Pipe.SinkChannel;
import java.nio.channels.Pipe.SourceChannel;
import org.junit.Test;
public class TestPipe {
@Test
public void test1() throws IOException{
//1、获取管道
Pipe pipe = Pipe.open();
//2、将缓冲区的数据写入管道
ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
SinkChannel sinkChannel = pipe.sink();//Pipe.SinkChannel是Pipe的内部类
byteBuffer.put("通过单向管道发送数据".getBytes());
byteBuffer.flip();
sinkChannel.write(byteBuffer);
byteBuffer.clear();
//3、读取缓冲区中的数据(可以是另一个线程)
SourceChannel sourceChannel = pipe.source();//Pipe.SourceChannel是Pipe的内部类
int len = sourceChannel.read(byteBuffer);
byteBuffer.flip();
System.out.println(new String(byteBuffer.array(),0,len));
sourceChannel.close();
sinkChannel.close();
}
}
本文最后,对之前几篇文章中提到的几个类,如Paths等的常用API做个整理,作为本系列最后补充吧。(后面开始整理Netty的知识点。)
NIO2中引入的几个实用类
随着 JDK 7 的发布, Java对NIO进行了极大的扩展,增强了对文件处理和文件系统特性的支持,以至于我们称他们为 NIO.2。因为 NIO 提供的一些功能, NIO已经成为文件处理中越来越重要的部分。
Path 与 Paths
java.nio.file.Path 接口代表一个平台无关的平台路径,描述了目录结构中文件的位置。
Paths 提供的 get() 方法用来获取 Path 对象
Path get(String first, String … more) : 用于将多个字符串串连成路径。
Path 常用方法:
boolean endsWith(String path) : 判断是否以 path 路径结束
boolean startsWith(String path) : 判断是否以 path 路径开始
boolean isAbsolute() : 判断是否是绝对路径
Path getFileName() : 返回与调用 Path 对象关联的文件名
Path getName(int idx) : 返回的指定索引位置 idx 的路径名称
int getNameCount() : 返回Path 根目录后面元素的数量
Path getParent() :返回Path对象包含整个路径,不包含 Path 对象指定的文件路径
Path getRoot() :返回调用 Path 对象的根路径
Path resolve(Path p) :将相对路径解析为绝对路径
Path toAbsolutePath() : 作为绝对路径返回调用 Path 对象
String toString() : 返回调用 Path 对象的字符串表示形式
Files 类
java.nio.file.Files 用于操作文件或目录的工具类。
Files常用方法:
Path copy(Path src, Path dest, CopyOption … how) : 文件的复制
Path createDirectory(Path path, FileAttribute<?> … attr) : 创建一个目录
Path createFile(Path path, FileAttribute<?> … arr) : 创建一个文件
void delete(Path path) : 删除一个文件
Path move(Path src, Path dest, CopyOption…how) : 将 src 移动到 dest 位置
long size(Path path) : 返回 path 指定文件的大小
Files 类
Files常用方法:用于判断
boolean exists(Path path, LinkOption … opts) : 判断文件是否存在
boolean isDirectory(Path path, LinkOption … opts) : 判断是否是目录
boolean isExecutable(Path path) : 判断是否是可执行文件
boolean isHidden(Path path) : 判断是否是隐藏文件
boolean isReadable(Path path) : 判断文件是否可读
boolean isWritable(Path path) : 判断文件是否可写
boolean notExists(Path path, LinkOption … opts) : 判断文件是否不存在
public static <A extends BasicFileAttributes> A readAttributes(Path path,Class<A> type,LinkOption...options) : 获取与 path 指定的文件相关联的属性。
Files常用方法: 用于操作内容
eekableByteChannel newByteChannel(Path path, OpenOption…how) : 获取与指定文件的连接,how 指定打开方式。
DirectoryStream newDirectoryStream(Path path) : 打开 path 指定的目录
InputStream newInputStream(Path path, OpenOption…how):获取 InputStream 对象
OutputStream newOutputStream(Path path, OpenOption…how) : 获取 OutputStream 对象