- ?工作过程中如何做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) {
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 {
}
}
}
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);
while (true){
byteBuffer.clear();
int read = inChanel.read(byteBuffer);
if(read == -1){
break;
}
byteBuffer.flip();
outChannel.write(byteBuffer);
}
}
}
点击-源代码地址:CodeChina