IO

10 篇文章 0 订阅

//updating

IO模型有阻塞IO、非阻塞IO、IO复用、信号驱动IO和异步IO,POSIX标准:同步和异步IO。IO:发起IO请求和实际的IO操作,同步IO和异步IO区别于第二步是否阻塞;阻塞IO和非阻塞IO区别于第一步发起IO请求是否会被阻塞,如果阻塞直到完成就是阻塞IO。

 

读(外存到内存:将数据从网卡到系统空间; 从系统空间到用户空间)输入流,写(将数据从用户空间到系统空间;从系统空间往网卡写)输出流。

 

字节流( 字符流(文本):流中最小的数据单元是字符, Java中的字符是Unicode编码,按一定编解码方式互转InputStreamReader、OutputStreamWriter ):有序、始、终点的字节序列。          

 

InputStream/Out(二进制格式操作):ByteArray(内存),File(外存),Piped(线程),Buffered,StringBuffer,Filter(可过滤),Object,Data(基本数据类型),; Reader/Writer:CharArray(内存),File,Piped,Buffered,String,Filter; 

RandomAccessFile(随机文件操作):可以从文件的任意位置输入输出。SequenceInputStream (  把多个输入流连接成一个) ,LineNumberReader/ LineNumberInputStream(读时记行),PushbackReader/ PushbackInputStream(缓存实现预读)。 

 

eg.: serverSocket.bind(8088);
while(!Thread.currentThread.isInturrupted())//死循环等待新连接到来

{executor.submit(new ConnectIOThread (serverSocket.accept();//));}

class ConnectIOThread extends Thread{
    private Socket socket;
    public ConnectIOThread (Socket socket){
       this.socket = socket;
    }
    public void run(){
      while(!Thread.currentThread.isInturrupted()&&!socket.isClosed()){//死循环读写
          String someThing = socket.read(); //阻塞直到有数据    socket.write();//       }
    }
}

 

 

XML生成:public static void save(List<SomeNode> persons, Writer writer::new OutputStreamWriter(new FileOutputStream(new File(getFilePath() + "/student.xml")), "UTF-8")) throws Throwable{  
        XmlSerializer serializer = Xml.newSerializer();  

BufferedWriter writer2 = new BufferedWriter(writer);//

serializer.setOutput(writer2);
        serializer.setOutput(writer);  

        serializer.startDocument("UTF-8", true);  
          
        serializer.startTag(null, "student");  
        for(SomeNodeperson : persons){  
            serializer.startTag(null, "student");              serializer.attribute(null, "id", person.getId().toString());  serializer.attribute(null, "group", person.group);  

serializer.startTag(null, "name");  serializer.text(person.getName());     serializer.endTag(null, "name");  

            serializer.startTag(null, "age");              serializer.text(person.getAge().toString());              serializer.endTag(null, "age");  
              
            serializer.endTag(null, "student");  
        }  
        serializer.endTag(null, "student");       
        serializer.endDocument();  
        writer.flush();  
        writer.close();  
    }  解析(基于流操作文件,根据节点回调):public List<SomeNode> pullParseXml(){  
        List<SomeNode> lists=null;  
        SomeNode student=null;  
        try {  
            XmlPullParserFactory factory=XmlPullParserFactory.newInstance();   
            XmlPullParser pullParser=factory.newPullParser();  //Xml.newPullParser(); 

            InputStream in=this.getClass().getClassLoader().getResourceAsStream("student.xml");  //<?xml version="1.0" encoding="utf-8"?>要顶格显示
            pullParser.setInput(in, "UTF-8");  
            int eventType=pullParser.getEventType();  
            while(eventType!=XmlPullParser.END_DOCUMENT){  
                String nodeName=pullParser.getName();  
                switch (eventType) {  
                case XmlPullParser.START_DOCUMENT:  //文档开始  
                     lists=new ArrayList<SomeNode>();          break;  
                case XmlPullParser.START_TAG:    //开始节点  
                    if("someNode".equals(nodeName)){  
                        student=new SomeNode();  
                        student.setId(pullParser.getAttributeValue(0));  //本节点属性值
                        student.setGroup(pullParser.getAttributeValue(1));  
                    }else if("name".equals(nodeName)){ // 开始子节点
                        student.setName(pullParser.nextText());  
                    }else if("age".equals(nodeName)){  
                        student.setAge(pullParser.nextText());  
                    }                    break;  
                case XmlPullParser.END_TAG:  
                    if("student".equals(nodeName)){  
                        lists.add(student);  
                        student=null;  
                    }     break;                  default:    break;  
                }  
                eventType=pullParser.next();  // 手动触发下一个事件
            }  
        } catch (Exception e) {              e.printStackTrace();          }  
        return lists;  
    }  

 

 

 

 

NIO(IO线程池:NIO并不是严格意义上的非阻塞IO而应该属于多路复用IO):Selector(允许1线程处理多个Channel,打开了多个连接(通道)时但每个连接的流量都不大,如聊天服务器) 基于流,Channel(“流”:UDP/TCP 网络,文件IO:SocketChannel,ServerSocketChannel,FileChannel,DatagramChannel),Buffer (通过IO发送的基本数据类型:ByteBuffer(DirectByteBuffer类似Buffer上的缓存,不是分配在堆上的,它不被GC直接管理,由系统内存进行分配,不被JVM管理(但Direct Buffer的JAVA对象是归GC管理的,只要GC回收了它的JAVA对象,系统才释放Direct Buffer所申请的空间);HeapByteBuffer分配在堆上,byte[]数组。创建和释放DirectByteBuffer的代价比HeapByteBuffer高,因为JVM堆中分配和释放内存比系统高效。把一个Direct Buffer写入一个Channel的速度要比把一HeapByteBuffer写入的快。 一个ByteBuffer经常被重用可考虑DirectByteBuffer对象,如果是需要经常释放和分配的地方用HeapByteBuffer) :CharBuffer,DoubleBuffer,FloatBuffer,IntBuffer,LongBuffer,ShortBuffer,Mappedyteuffer(内存映射文件) )。

通过Buffer (缓冲区内存:capacity,position(写时,表当前位置,position会向前移动到下一个可插入数据的Buffer单元。最大为capacity – 1,初始值为0;读时,position向前移动到下一个可读的位置),limit(写时,表最多能往Buffer里写多少数据,为capacity;读时, 表最多能读到多少数据,会被设置成写时的position值,即能读到之前写入的所有数据) ) 读写,可以从通道中读取数据,又可以写数据到通道,通道可异步读写,但流的读写通常是单向的。buffer.flip()从写模式切换到读,会将position设回0,limit设置成之前position值,position现在用于标记读的位置,limit表示之前写进了多少,现在就能读出多少。

Reactor模式:interface ChannelHandler{

      void channelReadable(Channel channel);
      void channelWritable(Channel channel);
 }
class Channel{
     Socket socket;
     Event event;//读,写或连接
}
class IoThread extends Thread{//IO线程主循环:
       public void run(){
         Channel channel;
         while(channel=Selector.select()){//选择就绪的事件和对应的连接
            if(channel.event==accept){
                registerNewChannelHandler(channel);//是新连接则注册新读写器
            }
            if(channel.event==write){
               getChannelHandler(channel).channelWritable(channel);//可以写,则写
            }
            if(channel.event==read){
              getChannelHandler(channel).channelReadable(channel);//可以读,则读
            }
         }
       }
    Map<Channel,ChannelHandler> handlerMap;//所有channel的对应事件处理器
}

 

 

NIO里何时可以读,比如socket主要的读、写、注册和接收函数,在等待就绪阶段都是非阻塞的,真正的I/O操作是同步阻塞的。AIO模型何时读完了

 

 

 

AIO:

网络:

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值