zoukankan      html  css  js  c++  java
  • java io

    设计模式

    装饰者模式、适配器模式

    类别

    同步阻塞IO(BIO)

    BIO是一个连接一个线程。

    传统的同步阻塞模型开发中,ServerSocket负责绑定IP地址,启动监听端口;Socket负责发起连接操作。连接成功后,双方通过输入和输出流进行同步阻塞式通信。

    该模型最大的问题就是缺乏弹性伸缩能力,当客户端并发访问量增加后,服务端的线程个数和客户端并发访问数呈1:1的正比关系,Java中的线程也是比较宝贵的系统资源,线程数量快速膨胀后,系统的性能将急剧下降,随着访问量的继续增大,系统最终就死-掉-了

    同步非阻塞IO(NIO)

    NIO提供了与传统BIO模型中的Socket和ServerSocket相对应的SocketChannel和ServerSocketChannel两种不同的套接字通道实现。两种通道都支持阻塞和非阻塞两种模式。

    对于低负载、低并发的应用程序,可以使用同步阻塞I/O来提升开发速率和更好的维护性;对于高负载、高并发的(网络)应用,应使用NIO的非阻塞模式来开发。

    • 缓冲区

      java.nio.Buffer是一个抽象类。

      在NIO库中,所有数据都是用缓冲区处理的,缓冲区包含一些要写入或者读出的数据。

      缓冲区实际上是一个数组,并提供了对数据结构化访问以及维护读写位置等信息。如:ByteBuffer、CharBuffer、 ShortBuffer、IntBuffer、LongBuffer、FloatBuffer、DoubleBuffer。

    • 通道

      我们对数据的读取和写入要通过Channel,它就像水管一样,是一个通道。通道不同于流的地方就是通道是双向的,可以用于读、写和同时读写操作。

      底层的操作系统的通道一般都是全双工的,所以全双工的Channel比流能更好的映射底层操作系统的API。

      • ​ SelectableChannel:用户网络读写
      • ​ FileChannel:用于文件操作
    • 多路复用器

      Selector提供选择已经就绪的任务的能力:Selector会不断轮询注册在其上的Channel,如果某个Channel上面发生读或者写事件,这个Channel就处于就绪状态,会被Selector轮询出来,然后通过SelectionKey可以获取就绪Channel的集合,进行后续的I/O操作。

      一个Selector可以同时轮询多个Channel,因为JDK使用了epoll()代替传统的select实现,所以没有最大连接句柄1024/2048的限制。所以,只需要一个线程负责Selector的轮询,就可以接入成千上万的客户端。

      • select和poll具有O(n)的无差别轮询复杂度
      • epoll事件复杂度为O(1),基于时间驱动的

    NIO是一个请求一个线程,即客户端发送的连接请求都会注册到多路复用器上,多路复用器轮询到连接有I/O请求时才启动一个线程进行处理。

    适用场景:聊天服务器

    异步非阻塞IO(AIO)

    NIO 2.0引入了新的异步通道的概念,并提供了异步文件通道和异步套接字通道的实现。

    异步的套接字通道是真正的异步非阻塞I/O,对应于UNIX网络编程中的事件驱动I/O(AIO)。他不需要过多的Selector对注册的通道进行轮询即可实现异步读写,从而简化了NIO的编程模型。

    • AsynchronousSocketChannel
    • AsynchronousServerSocketChannel
    • AsynchronousFileChannel
    • AsynchronousDatagramChannel

    AIO是一个有效请求一个线程,客户端的I/O请求都是由OS先完成了再通知服务器应用去启动线程进行处理。

    适用场景:相册服务器

    根据处理数据类型分类

    流式

    主体部分

    字节流

    按字节读,可用于文件、图片、视频、音频

    OutputStream、InputStream

    字符流

    按字符读,一般用于文件

    Writer、Reader

    Java中字符是采用Unicode标准,一个字符是16位,即一个字符使用两个字节来表示。为此,JAVA中引入了处理字符的流。因为数据编码的不同,而有了对字符进行高效操作的流对象。本质其实就是基于字节流读取时,去查了指定的码表。

    字节流没有缓冲区,是直接输出的,而字符流是输出到缓冲区的。因此在输出时,字节流不调用close()方法时,信息已经输出了,而字符流只有在调用close()方法关闭缓冲区时,信息才输出。要想字符流在未关闭时输出信息,则需要手动调用flush()方法。

    非流式

    辅助流式部分的类,如:File、RandomAccessFile、FileDescriptor

    其他类

    文件读取部分的与安全相关的类,如:SerializablePermission;

    与本地操作系统相关的文件系统的类,如:FileSystem、Win32FileSystem、WinNTFileSystem。

    根据数据来源/操作对象分类

    • 1、文件(file):FileInputStream、FileOutputStream、FileReader、FileWriter
    • 2、数组([]):
      • 2.1、字节数组(byte[]):ByteArrayInputStream、ByteArrayOutputStream
      • 2.2、字符数组(char[]):CharArrayReader、CharArrayWriter
    • 3、管道操作:PipedInputStream、PipedOutputStream、PipedReader、PipedWriter
    • 4、基本数据类型:DataInputStream、DataOutputStream
    • 5、缓冲操作:BufferedInputStream、BufferedOutputStream、BufferedReader、BufferedWriter
    • 6、打印:PrintStream、PrintWriter
    • 7、对象序列化反序列化:ObjectInputStream、ObjectOutputStream
    • 8、转换:InputStreamReader、OutputStreWriter
    • 9、字符串(String)Java8中已废弃StringBufferInputStream、StringBufferOutputStream、StringReader、StringWriter

    面试题

    1. 什么是IO流?
      它是一种数据的流从源头流到目的地。比如文件拷贝,输入流和输出流都包括了。输入流从文件中读取数据存储到进程(process)中,输出流从进程中读取数据然后写入到目标文件。

    2. 字节流和字符流的区别。
      字节流在JDK1.0中就被引进了,用于操作包含ASCII字符的文件。JAVA也支持其他的字符如Unicode,为了读取包含Unicode字符的文件,JAVA语言设计者在JDK1.1中引入了字符流。ASCII作为Unicode的子集,对于英语字符的文件,可以可以使用字节流也可以使用字符流。

    3. Java中流类的超类主要由那些?

      • java.io.InputStream
      • java.io.OutputStream
      • java.io.Reader
      • java.io.Writer
    4. FileInputStream和FileOutputStream是什么?
      这是在拷贝文件操作的时候,经常用到的两个类。在处理小文件的时候,它们性能表现还不错,在大文件的时候,最好使用BufferedInputStream (或 BufferedReader) 和 BufferedOutputStream (或 BufferedWriter)

      public class InputAndOutputBuffering {
          public static void main(String args[]) throws IOException {
              FileInputStream fistream = new FileInputStream("pqr.txt");
              BufferedInputStream bistream = new BufferedInputStream(fistream);
              
              FileOutputStream fostream = new FileOutputStream("xyz.txt");
              BufferedOutputStream bostream = new BufferedOutputStream(fostream);
              
              int temp;
              while( ( temp = bistream.read() ) != -1 ) {
                  bostream.write(temp);
                  System.out.print((char) temp);
              }
              bostream.close();
              fostream.close();
              bistream.close();
              fistream.close();
          }
      }
      
    5. 字节流和字符流,你更喜欢使用拿一个?
      个人来说,更喜欢使用字符流,因为他们更新一些。许多在字符流中存在的特性,字节流中不存在。比如使用BufferedReader而不是BufferedInputStreams或DataInputStream,使用newLine()方法来读取下一行,但是在字节流中我们需要做额外的操作。

    6. System.out.println()是什么?
      println是PrintStream的一个方法。out是一个静态PrintStream类型的成员变量,System是一个java.lang包中的类,用于和底层的操作系统进行交互。

    7. 什么是Filter流?
      Filter Stream是一种IO流主要作用是用来对存在的流增加一些额外的功能,像给目标文件增加源文件中不存在的行数,或者增加拷贝的性能。

    8. 有哪些可用的Filter流?
      在java.io包中主要由4个可用的filter Stream。两个字节filter stream,两个字符filter stream,分别是FilterInputStream, FilterOutputStream, FilterReader and FilterWriter。这些类是抽象类,不能被实例化的。

    9. SequenceInputStream的作用?
      在拷贝多个文件到一个目标文件的时候是非常有用的。可用使用很少的代码实现

      public class TwoFiles {
          public static void main(String args[]) throws IOException {
              FileInputStream fistream1 = new FileInputStream("A.txt");  // first source file
              FileInputStream fistream2 = new FileInputStream("B.txt");  //second source file
      
              SequenceInputStream sistream = new SequenceInputStream(fistream1, fistream2);
              FileOutputStream fostream = new FileOutputStream("C.txt");// destination file
      
              int temp;
              while( ( temp = sistream.read() ) != -1) {
                  System.out.print( (char) temp ); // to print at DOS prompt
                  fostream.write(temp);   // to write to file
              }
              fostream.close();
              sistream.close();
              fistream1.close();
              fistream2.close();
          }
      }
      
    10. 说说PrintStream和PrintWriter
      他们两个的功能相同,但是属于不同的分类。字节流和字符流。他们都有println()方法。

    11. 在文件拷贝的时候,那一种流可用提升更多的性能?
      在字节流的时候,使用BufferedInputStream和BufferedOutputStream。
      在字符流的时候,使用BufferedReader 和 BufferedWriter

    12. 说说管道流(Piped Stream)
      有四种管道流, PipedInputStream, PipedOutputStream, PipedReader 和 PipedWriter.在多个线程或进程中传递数据的时候管道流非常有用。

    13. 说说File类
      它不属于 IO流,也不是用于文件操作的,它主要用于知道一个文件的属性,读写权限,大小等信息。

    14. 说说RandomAccessFile?
      它在java.io包中是一个特殊的类,既不是输入流也不是输出流,它两者都可以做到。他是Object的直接子类。通常来说,一个流只有一个功能,要么读,要么写。但是RandomAccessFile既可以读文件,也可以写文件。 DataInputStream 和 DataOutStream有的方法,在RandomAccessFile中都存在。

    作者:艾贺521 链接:https://www.imooc.com/article/24305

  • 相关阅读:
    双色球随机一注
    if else的简写
    select
    预解析
    json
    数组方法
    arguments
    国密SM4算法
    AES算法
    Feistel算法结构与DES加密算法
  • 原文地址:https://www.cnblogs.com/angelica-duhurica/p/11435058.html
Copyright © 2011-2022 走看看