Java-IO_NIO_AIO

Java-IO_NIO_AIO

sf2gis@163.com

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.csdn.net/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=.

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

弗里曼的小伙伴

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值