在传送文件的时候常常出现这么一个问题,就是当客户端的文件全部传送完了之后,服务器没有接收到客户端那边传过的停止信号,所以服务器也就跟着客户端停止运行了,我们可以使用
try {
socket.shutdownOutput();
} catch (IOException e) {
throw new RuntimeException(e);
}
这么一段代码使客户端的soket连接中断,这样就告诉了服务器那边 客户端已经运行完了
这三个输入流在 Java 中都用于从各种源(如文件、网络、内存等)中读取数据,但它们之间有一些区别:
-
InputStream
是所有字节输入流的抽象类,它是字节输入流的基类。它提供了读取字节的基本方法,但是不能直接处理字符数据。 -
InputStreamReader
是字节流到字符流的桥梁。它将字节流转换为字符流,可以指定编码方式,方便地读取字符数据。 -
BufferedInputStream
是对输入流的缓冲,它实际上是一个装饰器模式的应用,用于提高输入流的读取效率。它通过在内存中建立一个缓冲区,减少了对磁盘的访问次数,提高了读取性能。
总结来说,InputStream
是字节输入流的抽象类,InputStreamReader
用于将字节流转换为字符流,而 BufferedInputStream
则是对输入流的缓冲,用于提高读取性能。
Buffer的主要作就是装入数据,然后输出数据,相当于一个竹筒,通过put方法放入数据,没放一些数据 Nuffer的position相应的就会向后移动一些位置。
当Buffer装入这些数据结束后,条用Buffer的flip()方法,该方法将limit设置为position所在位置,评奖position设为0,这就是的Buffer的读写指针又移到了开始的位置,也就是卓,Buffer调用flip()方法之后,BUffer为输出数据做好准备,当Buffer输出数据结束之后,Buffer调用clear方法,clear()不是将Buffer里面的数据清空,它仅仅只是将position的位置设置为0,后面的数据会将position后面的数据覆盖,将limit设置为capacity,这样就为后面再一次装入数据做好准备
Buffer的样子
在这里需要区分rewind和flip方法
flip()
和 rewind()
是 ByteBuffer 类中的两个重要方法,它们都用于在读写操作之间调整缓冲区的位置和限制。
-
flip() 方法:
flip()
方法的作用是将缓冲区从写模式切换到读模式。在写模式下,通过put()
方法向缓冲区写入数据时,position 会逐渐增加,limit 则保持不变。而在读模式下,准备从缓冲区中读取数据时,需要将 position 设置为 0,同时将 limit 设置为之前的 position,以限制读取的数据范围。- 具体来说,
flip()
方法会将 limit 设置为当前 position,然后将 position 设置为 0,这样就完成了从写模式到读模式的切换。
-
rewind() 方法:
rewind()
方法的作用是将 position 设置为 0,以便重新读取缓冲区中的数据,而不影响 limit 的值。这意味着可以重复读取缓冲区中的数据,而不必改变 limit 的设定。- 通常情况下,
rewind()
方法用于在再次读取先前写入的数据之前,将 position 设置为 0。
Channel可以直接将指定文件的部分或者全部直接映射成Buffer
文件在计算机中实际上是存储在磁盘上的,但在程序运行时,文件内容会被读取到计算机的内存中进行处理。当你打开一个文件时,操作系统会将文件的内容加载到内存中,以便程序可以直接从内存中读取和操作文件数据。
当你使用传统的文件 I/O 操作(比如使用InputStream和OutputStream)时,需要显式地将文件内容从磁盘读取到内存中,并且在写入文件时也需要将数据从内存写回到磁盘。这个过程涉及了磁盘 I/O 操作,而磁盘访问通常比内存访问要慢得多。
而通过NIO中的文件映射(FileChannel.map()方法),可以直接将文件的部分或全部内容映射到内存中的ByteBuffer中,从而实现基于内存的文件读写操作。这样可以避免传统的文件I/O操作,提高了文件I/O操作的性能和灵活性。
因此,无论是传统的文件 I/O 操作还是NIO中的文件映射,文件内容都会被加载到计算机的内存中进行处理。
非阻塞的NIO连接方式差不多是这个样子