漫画:一文学会面试中常问的 IO 问题!

栏目: Java · 发布时间: 4年前

内容简介:作者 | 漫话编程

漫画:一文学会面试中常问的 IO 问题!

漫画:一文学会面试中常问的 IO 问题!

作者 | 漫话编程

责编 | 伍杏玲

本文经授权转载自漫话编程(ID:mhcoding)

周末午后,在家里面进行电话面试,我问了面试者几个关于IO的问题,其中包括什么是BIO、NIO和AIO?三者有什么区别?具体如何使用等问题,但是面试者回答的并不是很满意。于是我在面试评价中写道:"对 Java 的IO提醒理解不够深入"。恰好被女朋友看到了。

漫画:一文学会面试中常问的 IO 问题!

漫画:一文学会面试中常问的 IO 问题!

漫画:一文学会面试中常问的 IO 问题!

漫画:一文学会面试中常问的 IO 问题!

漫画:一文学会面试中常问的 IO 问题!

Java IO

IO,常协作I/O,是Input/Output的简称,即输入/输出。通常指数据在内部存储器(内存)和外部存储器(硬盘、优盘等)或其他周边设备之间的输入和输出。

输入/输出是信息处理系统(例如计算机)与外部世界(可能是人类或另一信息处理系统)之间的通信。

输入是系统接收的信号或数据,输出则是从其发送的信号或数据。

在Java中,提供了一些列API,可以供开发者来读写外部数据或文件。我们称这些API为Java IO。

IO是Java中比较重要,且比较难的知识点,主要是因为随着Java的发展,目前有三种IO共存。分别是BIO、NIO和AIO。

漫画:一文学会面试中常问的 IO 问题!

漫画:一文学会面试中常问的 IO 问题!

漫画:一文学会面试中常问的 IO 问题!

漫画:一文学会面试中常问的 IO 问题!

Java BIO、NIO

BIO 全称Block-IO 是一种同步且阻塞的通信模式。是一个比较传统的通信方式,模式简单,使用方便。但并发处理能力低,通信耗时,依赖网速。

Java NIO,全程 Non-Block IO ,是Java SE 1.4版以后,针对网络传输效能优化的新功能。是一种非阻塞同步的通信模式。

NIO 与原来的 I/O 有同样的作用和目的, 他们之间最重要的区别是数据打包和传输的方式。原来的 I/O 以流的方式处理数据,而 NIO 以块的方式处理数据。

面向流的 I/O 系统一次一个字节地处理数据。一个输入流产生一个字节的数据,一个输出流消费一个字节的数据。

面向块的 I/O 系统以块的形式处理数据。每一个操作都在一步中产生或者消费一个数据块。按块处理数据比按(流式的)字节处理数据要快得多。但是面向块的 I/O 缺少一些面向流的 I/O 所具有的优雅性和简单性。

漫画:一文学会面试中常问的 IO 问题!

Java AIO

Java AIO,全程 Asynchronous IO,是异步非阻塞的IO。是一种非阻塞异步的通信模式。

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

漫画:一文学会面试中常问的 IO 问题!

漫画:一文学会面试中常问的 IO 问题!

漫画:一文学会面试中常问的 IO 问题!

漫画:一文学会面试中常问的 IO 问题!

漫画:一文学会面试中常问的 IO 问题!

三种IO的区别

首先,我们站在宏观的角度,重新画一下重点:

BIO (Blocking I/O):同步阻塞I/O模式。

NIO (New I/O):同步非阻塞模式。

AIO (Asynchronous I/O):异步非阻塞I/O模型。

那么,同步阻塞、同步非阻塞、异步非阻塞都是怎么回事呢?关于这部分内容也可以查看《 漫话:如何给女朋友解释什么是IO中的阻塞、非阻塞、同步、异步? 》。

同步阻塞模式:这种模式下,我们的工作模式是先来到厨房,开始烧水,并坐在水壶面前一直等着水烧开。

同步非阻塞模式:这种模式下,我们的工作模式是先来到厨房,开始烧水,但是我们不一直坐在水壶前面等,而是回到客厅看电视,然后每隔几分钟到厨房看一下水有没有烧开。

异步非阻塞I/O模型:这种模式下,我们的工作模式是先来到厨房,开始烧水,我们不一一直坐在水壶前面等,也不隔一段时间去看一下,而是在客厅看电视,水壶上面有个开关,水烧开之后他会通知我。

阻塞VS非阻塞:人是否坐在水壶前面一直等。

同步VS异步:水壶是不是在水烧开之后主动通知人。

漫画:一文学会面试中常问的 IO 问题!

漫画:一文学会面试中常问的 IO 问题!

漫画:一文学会面试中常问的 IO 问题!

漫画:一文学会面试中常问的 IO 问题!

漫画:一文学会面试中常问的 IO 问题!

适用场景

BIO方式适用于连接数目比较小且固定的架构,这种方式对服务器资源要求比较高,并发局限于应用中,JDK1.4以前的唯一选择,但程序直观简单易理解。

NIO方式适用于连接数目多且连接比较短(轻操作)的架构,比如聊天服务器,并发局限于应用中,编程比较复杂,JDK1.4开始支持。

AIO方式适用于连接数目多且连接比较长(重操作)的架构,比如相册服务器,充分调用OS参与并发操作,编程比较复杂,JDK7开始支持。

漫画:一文学会面试中常问的 IO 问题!

漫画:一文学会面试中常问的 IO 问题!

漫画:一文学会面试中常问的 IO 问题!

使用方式

分别使用BIO、NIO、AIO 实现文件的读取和写入:

//Initializes The Object
User1 user = new User1();
user.setName("hollis");
user.setAge(23);
System.out.println(user);

//Write Obj to File
ObjectOutputStream oos = null;
try {
    oos = new ObjectOutputStream(new FileOutputStream("tempFile"));
    oos.writeObject(user);
} catch (IOException e) {
    e.printStackTrace();
} finally {
    IOUtils.closeQuietly(oos);
}

//Read Obj from File
File file = new File("tempFile");
ObjectInputStream ois = null;
try {
    ois = new ObjectInputStream(new FileInputStream(file));
    User1 newUser = (User1) ois.readObject();
    System.out.println(newUser);
} catch (IOException e) {
    e.printStackTrace();
} catch (ClassNotFoundException e) {
    e.printStackTrace();
} finally {
    IOUtils.closeQuietly(ois);
    try {
        FileUtils.forceDelete(file);
    } catch (IOException e) {
        e.printStackTrace();
    }
}

//Initializes The Object
User1 user = new User1();
user.setName("hollis");
user.setAge(23);
System.out.println(user);

//Write Obj to File
ObjectOutputStream oos = null;
try {
    oos = new ObjectOutputStream(new FileOutputStream("tempFile"));
    oos.writeObject(user);
} catch (IOException e) {
    e.printStackTrace();
} finally {
    IOUtils.closeQuietly(oos);
}

//Read Obj from File
File file = new File("tempFile");
ObjectInputStream ois = null;
try {
    ois = new ObjectInputStream(new FileInputStream(file));
    User1 newUser = (User1) ois.readObject();
    System.out.println(newUser);
} catch (IOException e) {
    e.printStackTrace();
} catch (ClassNotFoundException e) {
    e.printStackTrace();
} finally {
    IOUtils.closeQuietly(ois);
    try {
        FileUtils.forceDelete(file);
    } catch (IOException e) {
        e.printStackTrace();
    }
}
static void readNIO() {
        String pathname = "C:\\Users\\adew\\Desktop\\jd-gui.cfg";
        FileInputStream fin = null;
        try {
            fin = new FileInputStream(new File(pathname));
            FileChannel channel = fin.getChannel();

            int capacity = 100;// 字节
            ByteBuffer bf = ByteBuffer.allocate(capacity);
            int length = -1;

            while ((length = channel.read(bf)) != -1) {

                bf.clear();
                byte[] bytes = bf.array();
                System.out.write(bytes, 0, length);
                System.out.println();
            }

            channel.close();

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fin != null) {
                try {
                    fin.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    static void writeNIO() {
        String filename = "out.txt";
        FileOutputStream fos = null;
        try {

            fos = new FileOutputStream(new File(filename));
            FileChannel channel = fos.getChannel();
            ByteBuffer src = Charset.forName("utf8").encode("你好你好你好你好你好");
            int length = 0;

            while ((length = channel.write(src)) != 0) {
                System.out.println("写入长度:" + length);
            }

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fos != null) {
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
public class ReadFromFile {
  public static void main(String[] args) throws Exception {
    Path file = Paths.get("/usr/a.txt");
    AsynchronousFileChannel channel = AsynchronousFileChannel.open(file);

    ByteBuffer buffer = ByteBuffer.allocate(100_000);
    Future<Integer> result = channel.read(buffer, 0);

    while (!result.isDone()) {
      ProfitCalculator.calculateTax();
    }
    Integer bytesRead = result.get();
    System.out.println("Bytes read [" + bytesRead + "]");
  }
}
class ProfitCalculator {
  public ProfitCalculator() {
  }
  public static void calculateTax() {
  }
}

public class WriteToFile {

  public static void main(String[] args) throws Exception {
    AsynchronousFileChannel fileChannel = AsynchronousFileChannel.open(
        Paths.get("/asynchronous.txt"), StandardOpenOption.READ,
        StandardOpenOption.WRITE, StandardOpenOption.CREATE);
    CompletionHandler<Integer, Object> handler = new CompletionHandler<Integer, Object>() {

      @Override       public void completed(Integer result, Object attachment) {
        System.out.println("Attachment: " + attachment + " " + result
            + " bytes written");
        System.out.println("CompletionHandler Thread ID: "
            + Thread.currentThread().getId());
      }

      @Override       public void failed(Throwable e, Object attachment) {
        System.err.println("Attachment: " + attachment + " failed with:");
        e.printStackTrace();
      }
    };

    System.out.println("Main Thread ID: " + Thread.currentThread().getId());
    fileChannel.write(ByteBuffer.wrap("Sample".getBytes()), 0, "First Write",
        handler);
    fileChannel.write(ByteBuffer.wrap("Box".getBytes()), 0, "Second Write",
        handler);

  }
}

漫画:一文学会面试中常问的 IO 问题!

漫画:一文学会面试中常问的 IO 问题!

漫画:一文学会面试中常问的 IO 问题!

漫画:一文学会面试中常问的 IO 问题!

滴滴滴,水开了。

漫画:一文学会面试中常问的 IO 问题!

漫画:一文学会面试中常问的 IO 问题!

 热 文推 荐 

Visual Basic 终于要衰落了吗?

华为“舵手”任正非

小米崔宝秋:小米 AIoT 深度拥抱开源

☞独家 | Vitalik Buterin:以太坊2.0之跨分片交易

☞如何在标准的机器学习流程上玩出新花样?

☞面试官:你简历中写用过docker,能说说容器和镜像的区别吗?

☞C++、 Python 、Rust、Scala构建编译器的差异性究竟有多大?

☞马云曾经偶像,终于把阿里留下的1400亿败光了!

你点的每个“在看”,我都认真当成了喜欢


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Algorithms Illuminated (Part 2)

Algorithms Illuminated (Part 2)

Tim Roughgarden / Soundlikeyourself Publishing, LLC / 2018-8-5 / USD 17.99

Algorithms are the heart and soul of computer science. Their applications range from network routing and computational genomics to public-key cryptography and machine learning. Studying algorithms can......一起来看看 《Algorithms Illuminated (Part 2)》 这本书的介绍吧!

SHA 加密
SHA 加密

SHA 加密工具

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具