Java IO流
-
概述
- IO流用来处理设备之间的数据传输 (上传文件和下载文件)
- java对数据的操作时通过流的方式
- java用于操作流的对象都在IO包中
-
IO流分类
- 流向分:
- 输入流(把文本拿到控制台, 读取数据)
- 输出流(把文本写到文件中, 写出数据)
- 数据类型分:
- 字节流
- 字符流(1个字符等于两个字节流,为了方便操作文本数据,Java就提供了字符流)
- 注:如果操作文本数据,就用字符流,其他情况就用字节流
- 流向分:
- 四个基(抽象)类 InputStream OutputStream Reader Writer
- IO第一个案例 : 往一个文本文件中输入一句话:hello io 采用 OutputStream
- 每种基类的子类都是以父类名作为后缀名
- OutputStream 的子类FileOutputStream的构造方法
- FileOutputStream(File file)
- FileOutputStream(String name)
- 用FileOutputStream的对象先调用write然后调用close(为什么要有close,1.让流对象关闭,2.通知系统释放有关的资源) 共三步
- 字节流写数据的方式有三个
- void write(int b) 一个字节
- void write(byte[] b) 字节数组
- void write(byte[] b, int off, int len) 字节数组的一部分
- 字节流写数据常见问题
- 创建字节输出流做了哪些事情?
- 系统创建文件 创建fileoutputstream对象 把对象指向文件
- 数据写成功后,为什么要close()?
- 让对象变成垃圾 让系统去释放资源
- 如何实现数据的追加写入
- FileOutputStream(File file, true)
- FileOutputStream(String name, true)
- 如何实现数据的换行?
- "\n"
- 创建字节输出流做了哪些事情?
- 字节流写数据加入异常处理
- 分开做异常处理 三步三个try(可读性差,一般不用)
- 一起做
- FileInputStream
- int read() 从此输入流中读取一个数据字节 (若到文件末尾则返回-1) int read(byte[] b) 从此输入流中将最多b.length个字节的数据读入到一个byte数组中 数组长度一般是1024或1024大的整数倍
- 返回值是实际读取的字节个数
- 会了,读写文件,练习复制文件
- 两个注意:数据源:从哪里来 目的地:到哪里去
- 在计算机中中文的存储分两个字节 第一个字节肯定是负数,第二个字节可能有正数,但是没影响
- 字节缓冲流
- 字节流一次读写一个数组的速度明显比一次读写一个字节的速度快很多,这是加入了数组这样的缓冲区效果,java本身在设计的时候,也考虑了这样的设计思想(装饰设计模式),所以提供了字节缓冲区流 ,这种类,也被称为缓冲区类(高效类) 包含 字节缓冲输出流 BufferedOutputStream字节缓冲区输入流 BufferedInputStream(2个构造)
- 构造方法可以指定缓冲区大小,但是我们一般用不上,因为默认的缓冲区大小就足够了
- 为什么不传递一个具体的文件或者文件路径,而是传递一个OutputStream对象呢?
- 因为字节缓冲区流仅仅提供缓冲区,为高效而设计,但是真正的读写操作还是得靠基本的流对象实现 (new BufferedOutputStream(OutputStream out))
- 读对象:BufferedInputStream 用法跟FileInputStream一样 read() 和read(char[] c)
- 写对象:BufferedOutputStream write(char[] a)
字节流四种方式复制文件:
* 基本字节流一次读取一个字节
* 基本字节流一次读取一个字节数组
* 高效字节流一次读取一个字节
* 高效字节流一次读取一个字节数组 -
字符流
- 概述:由于字节流操作中文不是特别方便,所以,java就提供了转换流
- 字符流 = 字节流 + 编码表
- 什么叫编码表
- ASCII码表 (美国标准信息交换码) 一个字节的7个位(-128-127)表示一个字符 最高位为符号位
- ISO-8859-1 拉丁码表 欧洲码表 8位表示一个数据 0-255
- gb2312 简体中文
- gbk 加入更多中文文字符号
- gb18030 gbk的取代版本
- BIG-5码 繁体码表
- Unicode 国际标准码 两个自己表示 java默认Unicode
- UTF -8 最多三个字节表示一个字符 能用一个就用一个 一个表示不了就用两个 实在不行就用三个 可以与 ASCII兼容
- 字符串中的编码问题
- String类的一个构造方法 String(byte[] bytes, String charsetName):通过指定的字符集解码字节数组
- byte[] getBytes(String charsetName) 使用指定的字符集将string编码为byte序列
- 编码: 把看的懂的变成看不懂的 解码:相反
- 编码问题简单,只要编码解码的格式是一致的,就不会有问题
- IO的编解
- OutputStreamWriter(OutputStream out):字符流 把字节流转换为字符流
- 必须通过转换流才能做
- OutputStreamWriter(OutputStream out, String charsetName):字符流 根据指定编码把字节流转换为字符流
- InputStreamReader(InputStream is) (此处可读取字符数组)
- InputStreamReader(InputStream is, String charsetName) 用指定字符编码来读取
OutputStreamWriter 的write() 方法共五个重载 - void write(int c) 写一个字符
- void write(char[] cbuf) 写一个字符数组
- void write(char[] cbuf, int off, int len)
- void write(String str) 写一个字符串
- void write(String str, int off, int len)
- 注意:字符流写数据记得要 void flush() 一下
- 运行close() 方法时,默认先刷新一下
- close() 和 flush()的区别
- close()关闭流对象,但是要刷新一次缓冲区,关闭之后,流对象不能在写数据了
- flush()仅仅刷新缓冲区,刷新后流对象还能继续使用(只有在数据量很大的情况下才需要flush())