Java中IO流操作、BIO、NIO、AIO*inputStream-字节输入流 outputStream-字节输出流 Reader-字符输入流 Writer-字符输出流

  • ?工作过程中如何做Java的IO操作的
    • ★ Java的IO操作从方向上分为:InputStream 和 OutputStream。
    • 从单位上有字节流和字符流,字节流可以通过StreamReader转换为字符流,为了提高效率我们也用到了Buffer流。
    • 深度回答:
    • ◆ 以上介绍的流操作都是BIO流,项目中直接操作IO的业务场景不太多。
    • 但是我了解很多分布式框架底层的通信都是使用 NIO流、NIO流最核心的组件就是Buffer、Chanel和Selector了。
    • ?你是怎么理解Java的数据流的?
    • ◆ 文件通常是由一连串的字节或字符构成,组成文件的字节序列称为’字节流’,组成文件的字符序列称为’字符流’。
    • ◆ Java 中根据流的方向可以分为输入流和输出流。
    • -输入流是将文件或其它输入设备的数据加载到内存的过程。
    • -输出流恰恰相反,是将内存中的数据保存到文件或其它输出设备。
    • ?BIO的通信模型:
    • ?说一你对BIO模型的理解吧?
    • -BIO:同步阻塞,服务器实现模式为一个连接一个线程,
    • 即客户端有连接请求时服务端就需要启动一个线程进行处理。
 *  ? BIO实现方式:
     *      ?BIO有那些实现方式?
     *          ◆ 传统BIO
     *              ‣ 采用BOI通信模型的服务端,通常由一个独立的Acceptor线程负责监听客户端的连接,无客户端连接即阻塞。
     *              ‣ 可以通过多线程来支持多个客户端的连接。
     *          ◆ 如何改进传统BIO 线程多开销大的弊端,如何改进?
     *              ‣伪异步BIO
     *               ▴ 为了解决同步阻塞I/O面临的一个链路需要一个线程处理的问题。
     *               ▴ 后端通过一个线程池来处理多个客户端的请求接入,形成客户端个数M:线程池最大线程数N的比例关系,其中M可以远远大于N。
     *               ▴ 通过线程池可以灵活地掉配线程资源,设置线程的最大值,防止由于海量并发接入导致线程耗尽。
     *
```java
*  ? NIO通信模型:
 *  NIO:同步非阻塞,服务器实现模式一个线程处理多个请求(连接)。
 *  三个特点:Selector(选择器)、Channel(信道)、Buffer(缓存)
 *                  ▴ Buffer 中的重要属性:
 *                      ➢ Capacity 容量,即可以容纳的最大数据量,在缓冲区创建时被设定并且不能改变。
 *                      ➢ Limit 表示缓存区的当前终点,不能对缓存区超过极限的位置进行读写操作。且极限是可以修改的。
 *                      ➢ Position 位置,下一个要被读或写的元素的索引,每次读写缓存数据时都会改变改值,为下次读写作准备。
 *                      ➢ Mark 标记
 *             ▴?NOI中Channel常用实现类:?
 *                   ▵ FileChannel:主要用来对本地文件进行IO操作。
 *                   ▵ DatagramChannel:用于UDP的数据读写。
 *                   ▵ SocketChannel:用于TCP的数据读写,客户端实现。
 *                   ▵ ServerSocketChannel:用于TCP的数据读写,服务实现。
 *          ▴?在Java NIO的Channel和流的区别??
 *              ◆ Channel是双向的,可读可写;流是单项的。
 *              ◆ Channel可以异步读写。
 *              ◆ Channel总是基于Buffer的。
 *   ?NIO的Selector??
 *   ▸ selector(选择器)是JavaNIO中能够检测一到多个NIO通道,并能够知晓是否为诸如读写事件做好准备的组件。
 *   -这样,一个单独的线程可以管理多个Channel,从而管理多个网络连接。
 *   ☞ Selector是一个抽象类,定义类一些主要的方法。有一个具体的实现selectorImpl
 *   如下:
 *      public abstract class Selector implements Closeable{
 *          public static Selector open();//得到一个选择器对象.
 *          public int select(long timeout);//阻塞timeout毫秒,监控所有注册的通道.
 *          public Set<SelectionKey> selectedKeys();//从内部集合中得到所有的SelectionKey.
 *      }
 *
```
 
 *  ?AIO又是什么?
 *  AIO:异步非阻塞,AIO引入异步通道的概念,
 *  采用 ProActor (主动器)模式,简化来程序编写,有效的请求才启动线程。
* @describe 传统的BIO的通讯模型 示例 单向读入/单向读出(没有线程池),同步阻塞,服务器实现模式为一个连接一个线程,
 * @requirement IO通信都涉及网络编程,inputStream-字节输入流 outputStream-字节输出流 Reader-字符输入流 Writer-字符输出流
 */
public class BioStreamDemo {
}
 class BioStreamDemo1 {
     public static void main(String[] args) {
         //定义一个服务器
         ServerSocket serverSocket;
         try {
             serverSocket = new ServerSocket(7777);
             //监听机制,当有新的连接那么需要创建一个线程
             while (true) {//为true直接监听状态
                 Socket socket = serverSocket.accept(); //阻塞的状态
                 //有连接来
                 new Thread(() -> {
                     try {
                         BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                         PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
                         String str = "";
                         while ((str = in.readLine()) != null) {
                             out.println("服务器端接受到的数据是: " + str);
                         }
                     } catch (IOException e) {
                         e.printStackTrace();
                     }
                 }).start();
             }
         } catch (IOException e) {
             e.printStackTrace();
         }finally {
             //关闭相关资源
         }
     }
     /**
      * 运行起来服务器后,在DOM 窗口:输入:telnet 127.0.0.1 7777  连接上输入信息,即可收到。
      */
 }
/**
 * 伪异步BIO的通讯模型 (存有线程池)
 */
class BioStreamDemo2 {
    public static void main(String[] args) throws Exception {
        //创建一个线程池
        ExecutorService pool = Executors.newCachedThreadPool();
        //定义一个服务器
        ServerSocket serverSocket = new ServerSocket(8888);
        while (true) {
            Socket socket = serverSocket.accept(); //阻塞的状态
            pool.execute(new Runnable() {
                @Override
                public void run() {
                    try{
                        BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                        PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
                        String str = "";
                        while ((str = in.readLine()) != null) {
                            out.println("服务器端接受到的数据是: " + str);
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            });
        }
    }
}
 * @describe NIO 同步非阻塞,服务器实现模式一个线程处理多个请求(连接)* @requirement 使用NIO完成文件复制
 */
public class NioStreamDemo {
}
class NioStreamDemo1 {
    public static void main(String[] args) throws Exception{

        FileInputStream fileInputStream = new FileInputStream("/java-basics/closeable-streams/src/main/resources/file/1");
        FileChannel inChanel = fileInputStream.getChannel();

        FileOutputStream fileOutputStream = new FileOutputStream("/java-basics/closeable-streams/src/main/resources/file/2");
        FileChannel outChannel = fileOutputStream.getChannel();

        ByteBuffer byteBuffer = ByteBuffer.allocate(1024);

        //将文件1内容读取到buffer中并写到文件2中
        while (true){
            byteBuffer.clear();
            int read = inChanel.read(byteBuffer);
            if(read == -1){
                break;
            }

            //将buffer中内容写到文件2中
            byteBuffer.flip();
            outChannel.write(byteBuffer);
        }
    }
}

点击-源代码地址:CodeChina

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值