IO流.
1 IO流: 在 Java中所有数据都是使用流读写的. 流是一组有顺序的, 有起点和终点的字节集合,是对数据传输的总称或抽象.
2 流的作用: 为数据源和目的地建立一个通道. 在写java代码时,都是基于 java程序的视角看待流向的.一般来说:
(1) 写代码 修改数据的都是输出流 (out…).
(2) 直接进行 数据读取是输入流 (in…).
3 (1) 按流向分: 输入流(Input) 输出流(Output).
(2) 按处理的数据分:
字节流 (OutputStream 输出字节流, InputStream 输入字节流)(基于二进制数据进行处理, 8位).
字符流 (Write 输出字符流, Read 输入字符流) (基于文本类型进行处理,16位).
(3) 字节流和字符流的转换:
字节输入流转字符输入流 需要用到 InputStreamReader. 该类的构造函数可以用到 InputStream 对象.
字节输出流转字符输出流 需要用到 OutputStreamWriter. 该类的构造函数可以用到 OutputStream 对象
IO的方式 通常分为3种, 同步阻塞的BIO、同步非阻塞的NIO、异步非阻塞的AIO.
BIO, 服务器实现模式为 一个连接一个线程, 适用于 连接数目比较小且固定的架构.
NIO, 服务器实现模式为 一个请求一个线程, 即客户端发送的连接请求都会注册到 多路复用器, 适用于 连接数目多且连接比较短的架构.
AIO, 服务器实现模式为 一个有效请求一个线程, 客户端的I/O请求都是由OS先完成了再通知服务器应用去启动线程进行处理, 适用于 连接数目多且连接比较长的架构.
字节流对比字符流.
1、两者每次读入的字节数是不确定的, 可能相同也可能不相同.
字节流操作的基本单元是 字节; 字符流操作的基本单元为 Unicode码元;
2、两者都有缓冲流.
字节流在操作的时候 本身不会用到缓冲区的, 是与文件本身直接操作的;
字符流在操作的时候 使用到缓冲区的.
(4) PrintWriter 打印流(打印数据到某个流对象). StringWriter 字符串输出流. 如字符串获取堆栈异常信息,可以通过PrintWriter和StringWriter结合来获取.
(5) 缓冲流 Buffered: 在输入流和出处流之间的缓冲,提高输出流的运行效率. 为什么需要有缓冲流?
答: 当我们用read()读取文件时,每读一个字节,访问一次硬盘,效率很低. 文件过大时,操作起来也不是很方便。因此我们需要用到buffer缓存流,当创建buffer对象时,会创建一个缓冲区数组. 然后当我们读一个文件时, 通过支持 mark 和 reset 方法先从硬盘中读到缓冲区, 待缓冲区满后再进行传送. 这样会大大减少读写次数,这样就可以节省很多时间, 效率会更高.
5 缓冲输出流 默认的追加方式是false(即覆盖),可以改为true就是追加不覆盖.
PrintWriter 和 BufferedWriter 缓冲输出流之后要 .flush 刷新才会显示.
(3) 按功能分:
6 节点流:直接与数据源相连,读取或者写入. 常用的节点流:
(1) 父类:InputStream、OutputStream、Reader、Writer
(2) 文件 FileInputStream、FileOutputStream、FileReader、FileWriter 文件进行处理的节点流
(3) 数组:ByteArrayInputStream、ByteArrayOutputStream、CharArrayReader、CharArrayWriter对数组进行处理的节点流(对应的不再是文件,而是内存中的一个数组)
(4) 字符串: StringReader、StringWriter对字符串进行处理的节点流
(5) 管道:PipedInputStream、PipedOutputStream、PipedReader、PipedWriter队管道进行处理的节点流.
7 处理流:直接使用节点流, 读写不方便. 为了更快的读写文件, 才有了处理流. 处理流和节点流一块使用,在节点流的基础上,再套接一层,套接在节点流上的就是处理流(处理流不能单独使用). 如BufferedWriter处理流的构造方法总是要带一个其他的流对象使用。提高读写文件的速度. 常用的处理流:
(1) 缓冲流:BufferedInputStream、BufferedOutputStream、BufferedReader、BufferedWriter
(2) 转换流:InputStreamReader、OutputStreamReader实现字节流和字符流之间的转换
(3) 数据流:DataInputStream、DataOutoutStream等提供将基础数据类型写入到文件中,或者读取出来.
File文件操作类. (非流式)
6 file 类写相对路径不建议在真实项目中使用. 项目中一般使用 ClassLoader.getResourceAsStream() (推荐) 通过相对路径获取输入流.
也可以使用 FileInputStream + 绝对路径(不推荐).
InputStream fis = null;
fis = new FileInputStream("C:\\Users\\hp\\IdeaProjects\\java web\\IO-learn\\data\\随便.txt"); //不推荐.
fis = this.getClass().getClassLoader().getResourceAsStream("随便.txt"); //推荐.
7 当前项目的编译路径 open module settings-> path.(也就是out文件夹里面的) 第一个就是当前项目的编译路径. 通过相对路径可以查找文件. 通过class 查找的相对路径是以当前class编译类的路径作为相对路径.通过classLoader查找的相对路径是以整个跟路径作为相对路径. 可以把一个文件夹用资源文件夹(Resources)标记, 然后在主界面Build ->Build project完成更新,就可以通过上述方式对其中的文件进行获取.
8 Source: 项目java源文件目录,会编译成class文件到编译路径. Resources: 项目资源文件夹,复制到项目编译路径.
9 (1) 序列化:把 Java对象转换为字节序列 的过程称对象的序列化. 为了解决对 对象流进行读写操作所引发的问题 (本质上是 Java对象和 二进制对象 的相互转换). 要实现 Serializable接口.
(2) 反序列化:把 字节序列恢复为对象 的过程称对象的反序列化.
10 (1) 深拷贝: 实现了 Serializable 接口, 可以实现深拷贝.
(2) 浅拷贝: 实现了 Cloneable 接口, 重写 clone()方法, 可以实现浅拷贝.