Java-IO_NIO_AIO
2016年4月5日
1目标:从与外部进行各种输入输出。
2原理:将外部数据作为字节流(stream)或字符流(reader)读入数据。
原始的数据流称为节点流,经过包装后的节点流称为处理流。处理流增加了缓冲和便捷操作。
3流程:读取流:打开文件,读取数据,关闭文件。写入流:打开文件,写入数据,关闭文件。
3.1 读取流:打开文件,读取数据,关闭文件。
BufferedReaderbr=new BufferedReader(new FileReader("aaa.txt"));
String strRead;
while((strRead=br.readLine())!=null){
System.out.println(strRead);
}
br.close();
3.2 写入流:打开文件,写入数据,关闭文件。
PrintWriterpw=new PrintWriter(new FileWriter("ccc.xx"));
pw.println("thisis string to print writer");
pw.println("123");
pw.close();
3.3 示例:读取文件后打印出来。写入数据到指定文件。
//Client.java
import java.io.*;
public class Client {
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
//read from reader
BufferedReaderbr=new BufferedReader(new FileReader("aaa.txt"));
String strRead;
while((strRead=br.readLine())!=null){
System.out.println(strRead);
}
br.close();
//write to writer
PrintWriterpw=new PrintWriter(new FileWriter("ccc.xx"));
pw.println("thisis string to print writer");
pw.println("123");
pw.close();
}
}
//结果
this is file.
这是文件。
END
//aaa.txt
this is file.
这是文件。
END
//ccc.xx
this is string to printwriter
123
4方法:文件File,操作文件和目录
示例:创建一个新文件,并显示路径、名称。
//Client.java
import java.io.*;
public class Client {
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
Filef=new File("aaa.txt");
BooleanbNew=f.createNewFile();
System.out.println("AbsolutePath="+f.getAbsolutePath()+",name="+f.getName()+",createnew="+bNew);
}
}
//结果
AbsolutePath=/home/sf/test/workspace/Client/aaa.txt,name=aaa.txt,createnew=true
4.1 使用文件过滤器FilenameFileter,返回指定的文件和路径
FilenameFilter 接口的accept()方法接受name和dir参数,添加过滤逻辑,得到能够返回true的文件和路径。
//Client.java
import java.io.*;
public class Client {
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
File f = new File(".");
// {//all files and paths
// String[] arrName = f.list();
// for (String name : arrName) {
// System.out.println(name);
// }
// }
{//filter .txt files and folders
String[] arrName = f.list(new FilenameFilter(){
@Override
public boolean accept(File dir, String name) {
// TODO Auto-generated method stub
return name.endsWith(".txt") ||new File(name).isDirectory();
}
});
for (String name : arrName) {
System.out.println(name);
}
}
}
}
//结果,过滤掉.xx文件
.settings
aaa.txt
src
bbb.txt
bin
5方法:字节流Stream处理8位Byte类型的IO,字符流Reader处理16位char类型的IO。
参考:http://www.51testing.com/html/85/258885-811659.html
http://blog.youkuaiyun.com/xiadasong007/article/details/4776913
5.1 区别与联系:Stream和Reader提供了基本相同的功能及子类,只是输入格式不同。两者使用InputStreamReader和OutputStreamWrite进行适配。
5.2 方法:字节流Stream,InputStream,OutputStream等
目标:提供基本字节流的IO及针对不同设备的特殊IO。
原理:jvm读写IO设备,以字节流的形式输出输出。
方法:将byte数组输入或输出
参考:http://www.runoob.com/java/java-files-io.html
//Client.java
import java.io.*;
public class Client {
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
//read from stream
FileInputStream fi=newFileInputStream("aaa.txt");
byte[] buff=new byte[100];
int iReaded=0;
while((iReaded=fi.read(buff))>0){
System.out.println(new String(buff,0,iReaded)+",readed="+iReaded);
}
fi.close();
//write to stream
FileOutputStream fo=newFileOutputStream("bbb.txt");
fo.write("abcxx".getBytes());
fo.close();
System.out.println("Write to Steam=bbb.txtabcxx");
}
}
//结果
this is file.
这是文件。
END
,readed=34
Write to Steam=bbb.txt abcxx
//aaa.txt
this is file.
这是文件。
END
//bbb.txt
abcxx
5.3 方法:字符流Reader,Writer
5.3.1目标:提供基于字符流的IO。
5.3.2原理:将字节流、字符串等解析为字符。
5.3.3流程:参见流程:读取流:打开文件,读取数据,关闭文件。写入流:打开文件,写入数据,关闭文件。
5.3.4方法:与Stream相似的子类。
缓冲字符流:BufferedReader。增加readLine()实用功能。
BufferedReader in = newBufferedReader(new InputStreamReader(conn.getInputStream()));
String strLine=null;
while((strLine=in.readLine())!=null){
strResult+=strLine;
}
System.out.println("response="+strResult);
用户输入:Scanner(替代BufferReader)。
6方法:系统标准流重定向System.setIn(),setOut(),setErr()。
参考:http://www.169it.com/tech-qa-java/article-16154326677047614285.html
示例:标准输出重定向到文件,然后再重定向到console。
//Client.java
import java.io.*;
public class Client {
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
//redirect to file
PrintStream ps=new PrintStream(new FileOutputStream("ccc.xx"));
PrintStream stdout=System.out;
System.setOut(ps);
System.out.println("System.out.println() is printinghere.");
ps.close();
System.setOut(stdout);
System.out.println("System.out.println() is printinghere.2");
}
}
//结果
System.out.println() isprinting here.2
//ccc.xx
System.out.println() isprinting here.
7方法:进程IO
进程Process具有标准输出、输出、错误流,可以用于交互。
示例:运行进程javac,获得输出的错误信息。
//Client.java
import java.io.*;
public class Client {
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
Process p=Runtime.getRuntime().exec("javac");
BufferedReader br=new BufferedReader(newInputStreamReader(p.getErrorStream()));
String buff =null;
while((buff= br.readLine())!=null){
System.out.println(buff);
}
}
}
//结果
Usage: javac <options><source files>
where possible optionsinclude:
-g Generate all debugginginfo
-g:none Generate no debugging info
-g:{lines,vars,source} Generate only some debugging info
-nowarn Generate no warnings
-verbose Output messages about whatthe compiler is doing
-deprecation Output source locations wheredeprecated APIs are used
-classpath <path> Specify where to find user classfiles and annotation processors
-cp <path> Specify where to find userclass files and annotation processors
-sourcepath <path> Specify where to find input sourcefiles
-bootclasspath <path> Override location of bootstrap classfiles
-extdirs <dirs> Override location of installedextensions
-endorseddirs <dirs> Override location of endorsed standardspath
-proc:{none,only} Control whether annotation processingand/or compilation is done.
-processor<class1>[,<class2>,<class3>...] Names of the annotationprocessors to run; bypasses default discovery process
-processorpath <path> Specify where to find annotationprocessors
-d <directory> Specify where to place generatedclass files
-s <directory> Specify where to place generatedsource files
-implicit:{none,class} Specify whether or not to generate classfiles for implicitly referenced files
-encoding <encoding> Specify character encoding used bysource files
-source <release> Provide source compatibility withspecified release
-target <release> Generate class files for specific VMversion
-version Version information
-help Print a synopsis ofstandard options
-Akey[=value] Options to pass to annotationprocessors
-X Print a synopsis ofnonstandard options
-J<flag> Pass <flag> directlyto the runtime system
-Werror Terminate compilation ifwarnings occur
@<filename> Read options and filenames fromfile
8方法:文件任意访问RandomAccessFile
设置文件位置seek(pos)。
//Client.java
import java.io.*;
public class Client {
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
RandomAccessFile ra=newRandomAccessFile("aaa.txt","r");
ra.seek(5);
String strRead;
while((strRead=ra.readLine())!=null){
System.out.println("readed="+newString(strRead.getBytes("UTF-8"),"UTF-8"));
}
ra.close();
}
}
//结果
readed=is file.
readed=END
//aaa.txt
this is file.
END
9方法:序列化
9.1 目标:将内存中的对象持久化到硬盘或网络上。
9.2 原理:将对象按字节流读写。
9.3 流程:实现Serialize接口(仅作为标识,无需实现任何方法)。使用ObjectOutputStream、ObjectInputStream读写。
参考:http://www.myexception.cn/j2se/318778.html
9.3.1实现Serialization接口:仅作为标识,无需实现任何方法。
class Person implementsSerializable{
9.3.2序列化到文件:ObjectOutputStream。
ObjectOutputStreamop=new ObjectOutputStream(new FileOutputStream("s.txt"));
op.writeObject(p1);
op.writeObject(p2);
op.writeObject(null);//thisis a flag for termination of file
op.close();
9.3.3从文件反序列化到对象:ObjectInputStream。
ObjectInputStreamip=new ObjectInputStream(new FileInputStream("s.txt"));
Object obj;
while((obj=ip.readObject())!=null){
Personp=(Person)obj;
System.out.println("readobj="+p.getName()+","+p.getAge());
}
ip.close();
9.3.4示例:写入两个对象+null结束标识,然后顺序读出。
//Client.java
import java.io.*;
public class Client {
public static void main(String[] args) throws IOException,ClassNotFoundException {
// TODO Auto-generated method stub
//write
Person p1=new Person();
p1.setName("a1");
p1.setAge(12);
Person p2=new Person();
p2.setName("ass");
p2.setAge(55);
ObjectOutputStreamop=new ObjectOutputStream(new FileOutputStream("s.txt"));
op.writeObject(p1);
op.writeObject(p2);
op.writeObject(null);//thisis a flag for termination of file
op.close();
//read
ObjectInputStreamip=new ObjectInputStream(new FileInputStream("s.txt"));
Object obj;
while((obj=ip.readObject())!=null){
Person p=(Person)obj;
System.out.println("readobj="+p.getName()+","+p.getAge());
}
ip.close();
}
}
class Person implements Serializable{
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
//结果
read obj=a1,12
read obj=ass,55
9.4 方法:定义不序列化的数据transient。
示例:male为transient,将不进行序列化,读取时使用默认值。
//Client.java
private transient int age
import java.io.*;
public class Client {
public static void main(String[] args) throws IOException,ClassNotFoundException {
// TODO Auto-generated method stub
//write
Person p1=new Person();
p1.setName("a1");
p1.setAge(12);
p1.setMale(true);
Person p2=new Person();
p2.setName("ass");
p2.setAge(55);
p2.setMale(true);
ObjectOutputStream op=new ObjectOutputStream(newFileOutputStream("s.txt"));
op.writeObject(p1);
op.writeObject(p2);
op.writeObject(null);//this is a flag for termination offile
op.close();
//read
ObjectInputStream ip=new ObjectInputStream(newFileInputStream("s.txt"));
Object obj;
while((obj=ip.readObject())!=null){
Person p=(Person)obj;
System.out.println("readobj="+p.getName()+","+p.getAge()+","+p.isMale());
}
ip.close();
}
}
class Person implementsSerializable{
private String name;
private int age;
privatetransient boolean male;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public boolean isMale() {
return male;
}
public void setMale(boolean male) {
this.male = male;
}
}
//结果:不带transient时,male全部为true,带有transient时,male为默认值false。
read obj=a1,12,false
read obj=ass,55,false
9.5 方法:自定义对象内部的序列化方法
9.5.1目标:自定义对象内部序列化的方法
9.5.2原是:实现Externalizable接口的序列化读写方法。
9.5.3流程:实现Externalizable接口,使用ObjectOutputStream、ObjectInputStream读写。
9.5.3.1 实现Externalizable接口:自定义如何处理对象内部数据的序列化。
publicvoid writeExternal(ObjectOutput out) throws IOException {
publicvoid readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
9.5.3.2 使用ObjectOutputStream、ObjectInputStream读写。
//write
ObjectOutputStreamout=new ObjectOutputStream(new FileOutputStream("s.txt"));
out.writeObject(stu1);
out.writeObject(stu2);
out.writeObject(null);
out.close();
//read
ObjectInputStreamin=new ObjectInputStream(new FileInputStream("s.txt"));
Object obj;
while((obj=in.readObject())!=null){
Student stu=(Student)obj;
System.out.println("read="+stu.getName()+",age="+stu.getAge()+",score="+stu.getScore());
}
in.close();
9.5.3.3 示例:将score,age两个属性在序列化时反转。
//Client.java
import java.io.*;
public class Client {
public static void main(String[] args) throws IOException, ClassNotFoundException{
// TODO Auto-generated method stub
Student stu1=new Student();
stu1.setName("s1");
stu1.setAge(10);
stu1.setScore(5);
Student stu2=new Student();
stu2.setName("s2");
stu2.setAge(12);
stu2.setScore(5);
//write
ObjectOutputStreamout=new ObjectOutputStream(new FileOutputStream("s.txt"));
out.writeObject(stu1);
out.writeObject(stu2);
out.writeObject(null);
out.close();
//read
ObjectInputStreamin=new ObjectInputStream(new FileInputStream("s.txt"));
Object obj;
while((obj=in.readObject())!=null){
Student stu=(Student)obj;
System.out.println("read="+stu.getName()+",age="+stu.getAge()+",score="+stu.getScore());
}
in.close();
}
}
class Student implements Externalizable{
public Student() {
super();
// TODO Auto-generated constructor stub
}
private String name;
private int age;
private int score;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public int getScore() {
return score;
}
public void setScore(int score) {
this.score = score;
}
@Override
publicvoid writeExternal(ObjectOutput out) throws IOException {
// TODO Auto-generated method stub
out.writeObject(name);
out.writeInt(score);//first write score
out.writeInt(age);
}
@Override
publicvoid readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
// TODO Auto-generated method stub
this.name=(String)(in.readObject());
this.age=in.readInt();//first read as age
this.score=in.readInt();
}
}
//结果:
read=s1,age=5,score=10
read=s2,age=5,score=12
10 方法:类的版本标识servialVersionUID
10.1 目标:区分类的不同版本。
10.2 原理:相同的servialVersionUID表示类的版本相同。
默认是1L,通过IDE的警告可以生成64位long数字。
参考:http://www.cnblogs.com/guanghuiqq/archive/2012/07/18/2597036.html
10.3 流程:实现Serialization接口,添加servialVersionUID属性。
class Student implements Serializable{
privatestatic final long serialVersionUID = 5092187866910248456L;
11 方法:NIO(new io)
11.1 目标:IO的升级版,使用内存映射文件处理IO,提高速度。
11.2 原理:内存映射文件使用channel表示,使用buffer作为缓冲。
11.3 流程:创建流,获取channel,读取buff,关闭资源。
11.3.1创建流:与基于IO相同。
FileInputStreamin=new FileInputStream("aaa.txt");
11.3.2获取channel:从IO中获取相应的channel。
FileChannelc=in.getChannel();
11.3.3读取buff:从channel中读取到buff。
while(c.read(buff)!=-1){
11.3.4关闭资源:关闭IO。
in.close();
11.3.5示例:读取指定文件中的内容。
//Client.java
import java.io.*;
import java.nio.*;
import java.nio.channels.*;
public class Client {
public static void main(String[] args) throws IOException,ClassNotFoundException {
// TODO Auto-generated method stub
FileInputStreamin=new FileInputStream("aaa.txt");
FileChannelc=in.getChannel();
ByteBuffer buff=ByteBuffer.allocate(100);
while(c.read(buff)!=-1){
System.out.println(new String(buff.array()));
}
in.close();
}
}
//结果
this is file.
END
//aaa.txt
this is file.
END
11.4 方法:channel,buffer,selector
参考:http://www.iteye.com/magazines/132-Java-NIO
11.4.1内存映射通道channel:通道,用于表示一段内存映射文件,由JVM管理进行内存映射。由IO获取。
11.4.2缓冲区buffer:与通道交互,用于读写内存映射文件到内存。有多种类型的buff。
为了便于操作,提供了容量capacity,当前位置position,最大使用位置limit。自定义标记mark(),转到mark位置reset(),。请求内存allocate()。读写翻转flip(),位置复位clear()。
11.4.3字符集charset:常用字符串GBK,UTF-8,ISO-8859-1。
11.4.4文件锁FileLock:FileChannel的lock()/tryLock()。
11.4.5选择器Selector:单线程轮询提供模拟AIO。
多个非阻塞式的的channel集合,注册后使用SelectionKey表示(包含所有感兴趣的事件、附加对象及相关属性)建立连接的channel。
11.4.5.1 流程:服务器:配置服务端通道和选择器,轮询(select(),可连接:连接后读写。可读:读写)。
客户端:配置客户端通道和选择器,轮询(select(),可连接:连接后读写。可读:读写)。
11.4.5.1.1 配置服务端通道和选择器:
Selector sel=Selector.open();
ServerSocketChannel serChannel=ServerSocketChannel.open();
serChannel.bind(newInetSocketAddress("127.0.0.1",35536));
serChannel.configureBlocking(false);
serChannel.register(sel, SelectionKey.OP_ACCEPT);
11.4.5.1.2 轮询:select()检查当前的连接状态,如果可连接,则连接后读写。可读:读写。
if(sk.isAcceptable()){
ServerSocketChannelserver=(ServerSocketChannel)sk.channel();
SocketChannel client=server.accept();
client.configureBlocking(false);
//write
client.write(ByteBuffer.wrap(new String("this isserver.").getBytes()));
client.register(sel,SelectionKey.OP_READ);
System.out.println("ServerAccepted.");
}
if(sk.isReadable()){
SocketChannel sc=(SocketChannel)(sk.channel());
ByteBufferbuff=ByteBuffer.allocate(1024);
sc.read(buff);
String content=new String(buff.array());
System.out.println("read="+content);
sk.interestOps(SelectionKey.OP_READ);
System.out.println("ServerReaded.");
}
11.4.5.2 示例:Selector模拟AIO。
//Server.java
package lee;
import java.io.*;
import java.net.*;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.util.Iterator;
public class Server {
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
Selector sel=Selector.open();
ServerSocketChannel serChannel=ServerSocketChannel.open();
serChannel.bind(new InetSocketAddress("127.0.0.1",35536));
serChannel.configureBlocking(false);
serChannel.register(sel, SelectionKey.OP_ACCEPT);
while(true){
System.out.println("Server iswaiting...");
sel.select();
Iterator<SelectionKey>it=sel.selectedKeys().iterator();
while(it.hasNext()){
SelectionKey sk=it.next();
it.remove();
if(sk.isAcceptable()){
ServerSocketChannelserver=(ServerSocketChannel)sk.channel();
SocketChannel client=server.accept();
client.configureBlocking(false);
//write
client.write(ByteBuffer.wrap(newString("this is server.").getBytes()));
client.register(sel,SelectionKey.OP_READ);
System.out.println("ServerAccepted.");
}
if(sk.isReadable()){
SocketChannelsc=(SocketChannel)(sk.channel());
ByteBufferbuff=ByteBuffer.allocate(1024);
sc.read(buff);
String content=new String(buff.array());
System.out.println("read="+content);
sk.interestOps(SelectionKey.OP_READ);
System.out.println("ServerReaded.");
}
}
}
}
}
//Client.java
package lee;
import java.io.*;
import java.net.*;
import java.nio.ByteBuffer;
importjava.nio.channels.SelectionKey;
importjava.nio.channels.Selector;
importjava.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Scanner;
public class Client {
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
SocketChannel channel = SocketChannel.open();
channel.configureBlocking(false);
Selector sel = Selector.open();
channel.connect(newInetSocketAddress("127.0.0.1", 35536));
channel.register(sel, SelectionKey.OP_CONNECT);
while (true) {
sel.select();
Iterator<SelectionKey> it =sel.selectedKeys().iterator();
while (it.hasNext()) {
SelectionKey sk = it.next();
it.remove();
if (sk.isConnectable()) {
SocketChannel client = (SocketChannel)sk.channel();
client.configureBlocking(false);
if (client.isConnectionPending()) {
client.finishConnect();
}
// write,need a thread to writ alone
Scanner in = new Scanner(System.in);
while (in.hasNext()) {
String strInput = in.nextLine();
client.write(ByteBuffer.wrap(strInput.getBytes()));
}
in.close();
client.register(sel, SelectionKey.OP_READ);
}
if (sk.isReadable()) {
SocketChannel sc = (SocketChannel)(sk.channel());
ByteBuffer buff =ByteBuffer.allocate(1024);
sc.read(buff);
String content = newString(buff.array());
System.out.println("read=" +content);
}
}
}
}
}
//结果:Client端
aaa
ccc
//结果:Server端
Server is waiting...
Server Accepted.
Server is waiting...
read=aaa
Server Readed.
Server is waiting...
read=ccc
Server Readed.
Server is waiting...
11.4.5.3 示例:Selector服务端和客户端多次交互。
//Server.java
package lee;
import java.io.*;
import java.net.*;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.util.Iterator;
public class Server {
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
Selector sel=Selector.open();
ServerSocketChannel serChannel=ServerSocketChannel.open();
serChannel.bind(newInetSocketAddress("127.0.0.1",35536));
serChannel.configureBlocking(false);
serChannel.register(sel, SelectionKey.OP_ACCEPT);
while(true){
System.out.println("Server iswaiting...");
sel.select();
Iterator<SelectionKey>it=sel.selectedKeys().iterator();
while(it.hasNext()){
SelectionKey sk=it.next();
it.remove();
if(sk.isAcceptable()){
ServerSocketChannel server=(ServerSocketChannel)sk.channel();
SocketChannel client=server.accept();
client.configureBlocking(false);
//write
client.write(ByteBuffer.wrap(newString("this is server.").getBytes()));
client.register(sel,SelectionKey.OP_READ);
System.out.println("ServerAccepted.");
}
if(sk.isReadable()){
SocketChannelsc=(SocketChannel)(sk.channel());
sc.write(ByteBuffer.wrap(newString("this is server 2.").getBytes()));
ByteBufferbuff=ByteBuffer.allocate(1024);
sc.read(buff);
String content=new String(buff.array());
System.out.println("read="+content);
sk.interestOps(SelectionKey.OP_READ);
System.out.println("ServerReaded.");
}
}
}
}
}
//Client.java
package lee;
import java.io.*;
import java.net.*;
import java.nio.ByteBuffer;
importjava.nio.channels.SelectionKey;
importjava.nio.channels.Selector;
importjava.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Scanner;
public class Client {
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
SocketChannel channel = SocketChannel.open();
channel.configureBlocking(false);
Selector sel = Selector.open();
channel.connect(newInetSocketAddress("127.0.0.1", 35536));
channel.register(sel, SelectionKey.OP_CONNECT);
while (true) {
sel.select();
Iterator<SelectionKey> it =sel.selectedKeys().iterator();
while (it.hasNext()) {
SelectionKey sk = it.next();
it.remove();
if (sk.isConnectable()) {
final SocketChannel client =(SocketChannel) sk.channel();
client.configureBlocking(false);
if (client.isConnectionPending()) {
client.finishConnect();
}
// write,need a thread to writ alone
Thread t0=new Thread(new Runnable(){
@Override
public void run() {
// TODO Auto-generated methodstub
Scanner in = newScanner(System.in);
while (in.hasNext()) {
String strInput =in.nextLine();
try {
client.write(ByteBuffer.wrap(strInput.getBytes()));
} catch (IOException e){
// TODOAuto-generated catch block
e.printStackTrace();
}
}
in.close();
}
});
t0.start();
client.register(sel, SelectionKey.OP_READ);
}
if (sk.isReadable()) {
SocketChannel sc = (SocketChannel)(sk.channel());
ByteBuffer buff =ByteBuffer.allocate(1024);
sc.read(buff);
String content = newString(buff.array());
System.out.println("read=" +content);
}
}
}
}
}
//结果:Client端
read=this is server.
aaa
read=this is server 2.
//结果:Server端
Server is waiting...
Server Accepted.
Server is waiting...
read=aaa_
12 方法: AIO(NIO.2)
12.1 目标:NIO的升级,增加了路径、文件的快捷操作类,增加异步处理方法。
12.2 原理:多线程IO。
12.3 流程:
12.4 方法:Paths、Files
路径操作:Path表示路径,Paths为快捷路径处理类。
文件操作:Files为快捷文件处理类,walkFileTree()可以浏览文件树,FileVisitor为文件或路径的处理类,可以处理文件(访问、访问失败)或路径(路径访问前、后)。
示例:使用Path和Files浏览目录和文件。
//Client.java
import java.io.*;
import java.nio.file.*;
importjava.nio.file.attribute.BasicFileAttributes;
public class Client {
public static void main(String[] args) throws IOException,ClassNotFoundException {
// TODO Auto-generated method stub
Pathpath=Paths.get(".");
System.out.println(path.getNameCount()+":"+path.toAbsolutePath());
Files.walkFileTree(path,new SimpleFileVisitor<Path>(){
@Override
publicFileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throwsIOException {
// TODO Auto-generated method stub
System.out.println("preVisitDirectory="+dir);
return super.preVisitDirectory(dir, attrs);
}
@Override
publicFileVisitResult visitFile(Path file, BasicFileAttributes attrs) throwsIOException {
// TODO Auto-generated method stub
System.out.println("visitFile="+file);
return super.visitFile(file, attrs);
}
@Override
publicFileVisitResult visitFileFailed(Path file, IOException exc) throws IOException{
// TODO Auto-generated method stub
System.out.println("visitFileFailed="+file);
return super.visitFileFailed(file, exc);
}
@Override
publicFileVisitResult postVisitDirectory(Path dir, IOException exc) throwsIOException {
// TODO Auto-generated method stub
System.out.println("postVisitDirectory="+dir);
return super.postVisitDirectory(dir, exc);
}
});
}
}
//结果
1:/home/sf/test/workspace/Client/.
preVisitDirectory=.
visitFile=./.project
preVisitDirectory=./.settings
visitFile=./.settings/org.eclipse.jdt.core.prefs
postVisitDirectory=./.settings
visitFile=./aaa.txt
preVisitDirectory=./src
visitFile=./src/Client.java
postVisitDirectory=./src
visitFile=./.classpath
preVisitDirectory=./bin
visitFile=./bin/Client$1.class
visitFile=./bin/Client.class
postVisitDirectory=./bin
visitFile=./aaa.txt~
postVisitDirectory=.