IO
只要是与内存程序通信的,就可以将其理解为IO。
内存中处理好的数据反馈到某个设备上,这才算IO。CPU是真正处理的实体,不算IO设备。
CPU是老大,内存是保护CPU的,任何东西要接触CPU都要先过内存这一关。
常见的几种IO:
向磁盘中读取写入数据,和远远的程序通信,向控制台输出数据。
网络IO
最重要的就是网络IO,网络IO才使得系统间的通信成为了可能。
浏览器访问Web应用服务就是一种IO。web应用访问数据库,和数据库服务器之间的通信是一种网络IO。数据库主备之间的备份是一种网络IO。两个系统client端和server端的通信是一种网络IO。dubbo的provider端和consumer端的通信也是一种网络IO。
IO无处不在。
字节与字符
IO传输数据都是基于字节的,也可以说是二进制数据。无论是字符还是对象,都会通过中间层转为字节处理。
要用字节流而不要用字符流,因为不同语言表达字符的数字(计算机内部都是用数字表示字符)不同,而字符转为字节遵循统一的编码标准。java的字符流是对字节流的包装,真正网络交互时,需要转为字节来进行。
字符集是字符与字节转换的映射表(或者叫做字典),常见字符集有utf-8,unicode,中文的有GB2312等等。
java程序用char表示字符,双字节编码,在进行IO操作之前,需要将其转为字节。举例:
一个汉字的utf-8编码为3个字节,一个英文字母的utf-8编码为一个字节。接收方解码字节流的时候,会将三个字节解析为一个汉字,一个字节解析为一个英文字母,可以区分的原因是,utf-8编码中的前缀字节代表语言种类。
一般来说,用相同的方式编解码(发送方用什么方式编码,接收方就要用什么方式来解码),否则就无法正确解析,或者出现乱码。
Socket和Channel
java的一次IO都要经过socket或者channel的过程。
java框架的EJB,webService,MQ,JDBC,HttpClient以及FTP等等都是基于socket或者channel方式的,可能协议有所不同。
socket通信需要关注的比如,能否连同,心跳,已经对方程序是否已经关闭。
再者比如连接超时,读取超时,如果不设置对应的时间,连接超时(180s后)可能直接抛出异常,读取超时会一直等待下去,知道进程被关闭或者被OS的socket自从超时所触发。
nagle算法,当socket交互双方有大量小数据交互时,将较小的包延迟发送,最大为200ms,防止对包的封装造成的网络负载的增加(20字节的包头,以及数据链路层对网络包的进一步封装)。
数据库
目前大部分java程序与数据库通信的API还是基于java的socket的,并且都是BIO的,无论是RDBMS还是NOSQL的。
java与数据库通信在socket基础上会建立不同的协议,JDBC是其中的一种。
数据库服务器端类似于SocketServer一样提供Socket服务,内部提供配套的连接池对应连接来进行处理。
java通过JDBC驱动程序与数据库服务端进行交互,该JDBC驱动程序内部完成了通过Socket的协议包装。