Java -- 新IO -- 目录
20.1 Java 新IO简介
20.2 缓冲区与Buffer
例:演示缓冲区的操作流程
Class : IntBufferDemo01
20.2.2 深入缓冲区操作
20.2.3 创建子缓冲区
20.2.4 创建只读缓冲区
20.2.5 创建直接缓冲区
20.3 通道
20.3.1 FileChannel
例:使用输出通道输出内容
Class : FileChannelDemo01
package lime.pri.limeNio._20_3_1.channeldemo; import java.io.File;
import java.io.FileOutputStream;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel; public class FileChannelDemo01 {
public static void main(String[] args) throws Exception {
String info[] = {"lime","oracle","Lime","Oracle"};
File file = new File("F:/channels/out.txt");
FileOutputStream output = null;
output = new FileOutputStream(file);
FileChannel fout = null;
fout = output.getChannel();
ByteBuffer buf = ByteBuffer.allocate(1024);
for(int i = 0;i < info.length;i++){
buf.put(info[i].getBytes());
buf.put("\n".getBytes());
}
buf.flip();
fout.write(buf);
fout.close();
output.close();
}
}
例:使用通道进行读写操作
Class :FileChannelDemo02
package lime.pri.limeNio._20_3_1.channeldemo; import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel; public class FileChannelDemo02 { public static void main(String[] args) throws Exception {
File file1 = new File("F:/channels/note.txt");
File file2 = new File("F:/channels/outnote.txt");
FileInputStream input = null;
FileOutputStream output = null;
input = new FileInputStream(file1);
output = new FileOutputStream(file2);
FileChannel fin = null;
FileChannel fout = null;
fin = input.getChannel();
fout = output.getChannel();
ByteBuffer buf = ByteBuffer.allocate(1024);
int temp = 0;
while((temp = fin.read(buf)) != -1){
buf.flip();
fout.write(buf);
buf.clear();
}
fin.close();
fout.close();
input.close();
output.close();
}
}
20.3.2 内存映射
内存映射可以把文件映射到内存中,这样文件内的数据就可以用内存读/写指令来访问,而不是用InputStream或OutputStream这样的I/O操作类,采用此种方式读取文件的速度是最快的。
提示:Java中访问文件内容的4中方法。
⊙ RandomAccessFile,随机读取数据,此种访问速度较慢。
⊙ FileInputStream,文件输入流,使用此种方式数度较慢。
⊙ 缓冲读取(例BufferedReader),使用此种方式访问速度较快。
⊙ 内存映射(MappedByteBuffer),使用此种方式读取速度最快。
例:内存映射
Class : FileChannelDemo03
package lime.pri.limeNio._20_3_2.channeldemo; import java.io.File;
import java.io.FileInputStream;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel; public class FileChannelDemo03 { public static void main(String[] args) throws Exception {
File file = new File("F:/channels/mappedByteBuffer.txt");
FileInputStream input = null;
input = new FileInputStream(file);
FileChannel fin = null;
fin = input.getChannel();
MappedByteBuffer mbb = null;
mbb = fin.map(FileChannel.MapMode.READ_ONLY, 0, file.length());
byte data[] = new byte[(int)file.length()];
int foot = 0;
while(mbb.hasRemaining()){
data[foot++] = mbb.get();
}
System.out.println(new String(data));
fin.close();
input.close();
}
}
20.4 文件锁:FileLock
在Java新IO中提供了文件锁的功能,这样当一个线程将文件锁定之后,其他线程是无法操作此文件的。要想进行文件的锁定操作,则要使用FileLock类完成,此类的对象需要依靠FileChannel进行实例化操作。
⊙ 共享锁:允许多个线程进行文件的读取操作。
⊙ 独占锁:只允许一个线程进行文件的读/写操作。
例:将文件锁定
Class : FileLockDemo
package lime.pri.limeNio._20_4.channeldemo; import java.io.File;
import java.io.FileOutputStream;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock; public class FileLockDemo { public static void main(String[] args) throws Exception {
File file = new File("F:/channels/fileLock.txt");
FileOutputStream output = null;
output = new FileOutputStream(file,true);
FileChannel fout = null;
fout = output.getChannel();
FileLock lock = fout.tryLock();
if(lock != null){
System.out.println(file.getName() + " 文件锁定300秒");
Thread.sleep(300000);
lock.release();
System.out.println(file.getName() + " 文件解除锁定");
}
fout.close();
output.close();
}
}
20.5 字符集:Charset
例:取得Charset类的全部编码
Class : GetAllCharsetDemo
package lime.pri.limeNio._20_5.channeldemo; import java.nio.charset.Charset;
import java.util.Iterator;
import java.util.Map;
import java.util.SortedMap; public class GetAllCharsetDemo { public static void main(String[] args) {
SortedMap<String, Charset> all = null;
all = Charset.availableCharsets();
Iterator<Map.Entry<String,Charset>> iter = null;
iter = all.entrySet().iterator();
while(iter.hasNext()){
Map.Entry<String, Charset> me = iter.next();
System.out.println(me.getKey() + " --> " + me.getValue());
}
}
}
例:编码-解码操作
Class : CharsetEnDeDemo
20.6 Selector
在新IO中Selector是一个极其重要的概念,在原来使用IO和Socket构造网络服务时,所有的网络服务经使用阻塞方式进行客户端的连接,而如果使用了新IO则可以构造一个非阻塞的的网络服务。
Selector类的常用方法:
⊙ public static Selector open() throws IOException : 打开一个选择器。
⊙ public abstract int select() throws IOException : 选择一组键,其相应的通道已为 I/O 操作准备就绪。
⊙ public abstract Set<SelectionKey> selectedKeys() : 返回此选择器的已选择键集。
在进行非阻塞网络开发时需要使用SelectableChannel类向Select类注册,而且在新IO中实现网络程序需要依靠ServerSocketChannel类与SocketChannel类,这两个类都是SelectableChannel的子类,SelectableChannel提供了注册Selector的方法和阻塞模式。
ServerSocketChannel类的常用方法:
⊙ public final SelectableChannel configureBlocking(boolean block) throws IOException : 调整此通道的阻塞模式。true:阻塞模式;false:非阻塞模式
⊙ public final SelectionKey register(Selector sel, int ops) throws ClosedChannelException : 向给定的选择器注册此通道,返回一个选择键。
⊙ public static ServerSocketChannel open() throws IOException : 打开服务器的套接字通道。
⊙ public abstract ServerSocket socket() : 返回与此通道关联的服务器套接字。
在使用register()方法时需要指定一个选择器(Selector对象)以及Select域,Selector对象可以通过Selector中的open()方法取得,而Selector域则在SelectionKey类中定义。
4中Selector域:
⊙ public static final int OP_ACCEPT = 1 << 4: 相当于ServerSocket中的accpet()操作。
⊙ public static final int OP_CONNECT = 1 << 3 :连接操作。
⊙ public static final int OP_READ = 1 << 0 : 读操作。
⊙ public static final int OP_WRITE = 1 << 2 : 写操作。
如果要使用服务器想客户端发送信息,则需要通过SelectionKey类中提供的方法判断服务器的操作状态。而要想取得客户端的连接也需要使用SelectionKey类。
SelectionKey常用的方法:
⊙ public abstract SelectableChannel channel() : 返回为之创建此键的通道。
⊙ public final boolean isAcceptable() : 测试此键的通道是否已准备好接受新的套接字连接。
⊙ public final boolean isConnectable() : 测试此键的通道是否已完成其套接字连接操作。
⊙ public final boolean isReadable() : 测试此键的通道是否已准备好进行读取。
⊙ public final boolean isWritable() : 测试此键的通道是否已准备好进行写入。
例:取得时间的服务器
Class : DateServer
package lime.pri.limeNio._20_6.channeldemo.selector; import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Date;
import java.util.Iterator;
import java.util.Set; public class DateServer { public static void main(String[] args) throws Exception {
int ports[] = {8000,8001,8002,8003,8005,8006}; //定义一组连接端口号
Selector selector = Selector.open(); //打开一个选择器
for(int i = 0;i < ports.length;i++){ //构造服务器的启动信息
ServerSocketChannel initSer = null; //声明ServerSocketChannel
initSer = ServerSocketChannel.open(); //打开服务器套接字通道
initSer.configureBlocking(false); //服务器配置为非阻塞
ServerSocket initSock = initSer.socket(); //检索此通道关联的服务器套接字
InetSocketAddress address = null; //表示监听地址
address = new InetSocketAddress(ports[i]); //实例化绑定地址
initSock.bind(address); //绑定地址
//注册选择器,相当于使用accept()方法接收
initSer.register(selector, SelectionKey.OP_ACCEPT);
System.out.println("服务器运行,在 " + ports[i] + " 端口监听。");
}
int keysAdd = 0; //接收一组SelectionKey
while((keysAdd = selector.select()) > 0){ //选择一组键,相应的通道已为IO准备就绪
Set<SelectionKey> selectedkeys = selector.selectedKeys(); //取出全部生成的key
Iterator<SelectionKey> iter = selectedkeys.iterator(); //实例化Iterator
while(iter.hasNext()){ //迭代全部的key
SelectionKey key = (SelectionKey)iter.next(); //取出每一个SelectionKey
if(key.isAcceptable()){ //判断客户端是否已经连接上
ServerSocketChannel server = (ServerSocketChannel)key.channel(); //取得Channel
SocketChannel client = server.accept(); // 接收新连接
client.configureBlocking(false); //设置成非阻塞状态
ByteBuffer outBuf = ByteBuffer.allocateDirect(1024); //开辟缓冲区
outBuf.put(("当前时间为:" + new Date()).getBytes()); //缓冲区设置内容
outBuf.flip(); //重置缓冲区
client.write(outBuf); //输出信息
client.close(); //关闭输出流
}
}
selectedkeys.clear(); //清除全部key
}
}
}
Console : telnet
啦啦啦
Java -- 新IO -- 目录的更多相关文章
- Java 新IO
NIO提供全新的底层I/O模型.与最初的java.io包中面向流(stream-oriented)概念不同,NIO采用了面向块的概念(block-oriented).在尽可能的情况下,I/O的操 ...
- Java——新IO 通道
import java.io.File; import java.io.FileOutputStream; import java.nio.ByteBuffer; import java.nio.ch ...
- 怎样获取java新IO的Path文件大小
import org.junit.Test; import java.io.IOException; import java.nio.file.Files; import java.nio.file. ...
- Java——新IO 缓冲区与Buffer
缓冲区和Buffer import java.nio.IntBuffer; //================================================= // File Na ...
- JAVA(六)数据库/网络编程/新IO
成鹏致远 | lcw.cnblog.com |2014-02-05 数据库 1.JDBC概述 JDBC(Java Database Connectivity,Java数据库连接)提供了一种与平台无关的 ...
- Java -- IO -- 目录
操作文件的类 -- -- File File类的基本介绍 使用File类操作文件 范例 -- -- 列出指定目录的全部内容 RandomAccessFile类 使用RandomAccessFile类写 ...
- Java 8特性尝鲜:新新IO
Java 8特性尝鲜:新新IO 在这个专题前面的文章中,我们已经看到,使用Java8的lambda表达式对现有的JDK1.2 I/O库的提升,主要是可以使用lambda表达式来构造java.io.Fi ...
- java 21 - 15 新IO流 NIO
1:JDK4 新IO要了解的类 Buffer(缓冲),Channer(通道) 2:JDK7 要了解的新IO类 Path:与平台无关的路径. Paths:包含了返回Path的静态方法. public ...
- java之io之File类的list()方法过滤目录的使用
java的io的知识中,File类必须掌握.File类是对文件或者文件夹的封装.它本身并不能对所封装的文件进行读写,它封装的只是文件或文件夹的周边知识,比如 大小啦,创建日期啦,路径啦等等. 如果Fi ...
随机推荐
- OCiOS开发:音频播放器 AVAudioPlayer
简单介绍 AVAudioPlayer音频播放器可以提供简单的音频播放功能.其头文件包括在AVFoudation.framework中. AVAudioPlayer未提供可视化界面,须要通过其提供的播放 ...
- 前端CSS - 相对定位,绝对定位,固定定位
前端CSS - 相对定位,绝对定位,固定定位 1.1 相对定位 position:relative 相对定位,就是微调元素位置的.让元素相对自己原来的位置,进行位置的微调. 也就是说,如果一个盒子想进 ...
- 2012Hulu校园招聘笔试题
一.填空 侧重逻辑思维,没有语言.具体技术考察,大部分属于组合数学.算法.比较基本的知识点有二元树节点树.最小生成树.Hash函数常用方法等. 二.编程题 1.正整数剖分 2.AOE关键路径 3.二元 ...
- node学习笔记9——cookie,session相关操作
下面讲的都是基Express及相关的包.所以在实践本篇文章之前,通过npm安装好Express, cookie-parser, cookie-session这三个安装包. 先简单说一下,如何用Expr ...
- SharePoint 2013 Support for Windows Server 2012 R2
Summary Currently, Microsoft SharePoint Server 2013 is not supported for installation on computers r ...
- Lucene系列四:Lucene提供的分词器、IKAnalyze中文分词器集成、扩展 IKAnalyzer的停用词和新词
一.Lucene提供的分词器StandardAnalyzer和SmartChineseAnalyzer 1.新建一个测试Lucene提供的分词器的maven项目LuceneAnalyzer 2. 在p ...
- Unity---------Mesh理解
Mesh顾名思义“网格”,Unity3D里面所有的模型都是由Mesh组成的,UI也不例外. 例如下图,模型上的一个个小网格就是Mesh,这些Mesh有不同的三维顶点(Vector3),共同组成了一个3 ...
- andorid ndk 各种坑啊 记录下
android jni代码回调java的问题 因为多线程原因会导致找不到java类,无法call函数的问题 问题1找不到java类 在JNI_OnLoad的时候 保存下来 JNIEXPORT jint ...
- Jenkins+Github配置【转】
一.GitHub上配置 前提:Jenkins能正常打开 将本地文件上传到GitHub上:进入终端 cd Documents cd project git clone https://github.co ...
- Java多线程——可阻塞的队列BlockingQueue
阻塞队列与Semaphore有些相似,但也不同,阻塞队列是一方存放数据,另一方释放数据,Semaphore通常则是由同一方设置和释放信号量. ArrayBlockingQueue 只有put方法和ta ...