欢迎光临散文网 会员登陆 & 注册

Java IO流-基本流

2023-03-02 14:29 作者:回到唐朝当少爷  | 我要投稿

IO流 基本流

IO流:存储和读取数据的解决方案

作用:读写数据(本地文件,网络)

按流的方向分:IO流分为输入流(读取)和输出流(写出)

按操作文件类型分:字节流(操作所有类型的文件)和字符流(只能操作纯文本文件)

纯文本文件:Windows自带的记事本打开能读懂 word文件,Excel文件不是纯文本文件

IO流体系

字节流:InputStream(字节输入流)和OutputStream(字节输出流)

字符流:Reader(字符输入流)和Writer(字符输出流)

上述均为抽象类

字节流

FileOutputStream

细节

  1. 创建字节输出流对象

    • 参数使字符串表示的路径或者是File对象均可

    • 如果文件不存在会创建一个新的文件,但要保证父级路径是存在的

    • 如果文件已经存在会清空文件

  2. 写数据

    • write方法的参数是整数,但是实际上写到本地文件中的整数是在ASCII上对应的字符

    • 97->a

  3. 释放资源

    • 每次使用完流后要释放资源

写数据的三种方式

换行写:

  • windows:\r\n

  • Linux:\n

  • Mac:\r

细节:

  • 在Windows操作系统中,java对回车换行进行了优化

  • 虽然完整的是\r\n,但是我们写其中一个\r或者\n,java也可以实现换行,因为它会在底层补全

建议:不要省略,还是写全比较好

续写:

如果想续写打开开关即可,传递true

FileInputStream

如果读不到了返回-1

书写细节:

  1. 创建字节输入流对象

    • 如果文件不存在就直接报错

  2. 读取数据

    • 一次读一个字节读出来的数据是在ASCII上对应的数字,空格为32

    • 读到文件末尾了read方法返回-1

  3. 释放资源

    • 先开的流最后关闭

注意:read读取一个数据移动一次指针,所以要注意拿一个变量接受fis.read()结果

一次读取多个字节:

一般创建1024的整数倍的数组

捕获异常

JDK7中捕获异常的写法

JDK9中捕获异常的写法

实际开发中,异常都是抛出处理,上述了解即可

字符集

计算机中,任意数据都是以二进制形式存储的,8位为1个字节,存储英文,一个字节就足以

  1. GB2312字符集:1980年发布,1981年5月1日实施的简体中文汉字编码国家标准,收录7445个图形字符,包含6763个简体汉字(台湾用不了)

  2. BIG5字符:太短地区繁体中文标准字符集,共收录13053个中文字,1984年实施

  3. GBK字符集(国标扩):2000年3月17日发布,收录21003个汉字,包含国家标准GB13000-1中的全部中日韩汉字和BIG5编码中的所有汉字Windows系统默认使用的就是GBK,不过系统显示为ANSI

  4. Unicode字符集:国际标准字符集,它将世界各种语言的每个字符定义唯一的编码,以满足跨语言,跨平台的文本信息转换

GBK完全兼容ASCII,英文用一个字节存储,汉字用两个字节存储 高位字节二进制一定以1开头,转成十进制后是一个负数(为了与英文区分开)

UFT-16编码规则:用2-4个字节保存 UTF-32编码规则:固定使用4个字节保存UTF-8编码规则:用1-4个字符保存英文字母1个字节,简体中文3个字节

UTF-8不是一个字符集!!!而是一个编码规则,Unicode才是字符集

乱码出现原因

  1. 字节流一次只读取一个字节,所以例如三个字节的汉字会被截断,每一段都是负数,而在ASCII表中没有负数

  2. 编码和解码方式不统一

所以不要用字节流读取文本文件,但是用字节流拷贝文本文件不会乱码

编码与解码

Java中的编码方法

Java中的解码方法

字符流

字符流的底层就是字节流

字符流=字节流+字符集

特点:

  • 输入流:一次读一个字节,遇到中文时,一次读多个字节

  • 输出流:底层会把数据按照指定的编码方式进行编码,变成字节再写到文件中

使用场景:对纯文本文件进行读写操作

FileReader

  1. 创建字符输入流对象

  1. 如果文件不存在直接报错

  2. 读取数据

  1. 细节1:按字节进行读取,读到中文一次读多个字节,读取后解码返回一个整数

    细节2:读到文件末尾了,read方法返回-1

  2. 释放资源

不带参数的read方法:

read()细节:

  1. read()默认也是一个字节一个字节地读取的,如果遇到中文就会一次读取多个

  2. 在读取之后,方法的底层还会进行解码并转成十进制 最终把这个十进制作为返回值 这个十进制的数据也表示在字符集上的数字 英文:文件里面二进制数据 0110 0001 read方法进行读取,解码并转为十进制97 中文:文件里面的二进制数据11100110 10110001 100010001 read方法进行读取,解码并转成十进制27721 我想看到中文汉字,就是把这些十进制数据再进行强转(char)就行了

带参数的read方法:

read(chars):读取数据,解码,强转三步合并了,把强转之后的字符放到数组当中

read(chars)可以看做空参的read+强制类型转换

FileWriter

  1. 创建字符输出流对象

    • 参数是字符串表示的路径或者File对象都可以

    • 如果文件不存在会创建一个新的文件,但要保证父级路径存在

    • 如果文件已存在则会清空文件,如果不想清空可以打开续写开关

  2. 写数据

    • 如果write方法的参数是整数,但是实际上写到本地文件中的是整数在字符集上对应的字符

  3. 释放资源

字符流底层原理

  1. 创建字符流输入对象

    • 底层:关联文件,并创建缓冲区(长度为8192的字节数组)

  2. 读取数据

    • 底层:

    1. 判断缓冲区中是否有数据可以读取

    2. 如果缓冲区中没有数据,就从文件中获取数据撞到缓冲区中,如果文件中也没有数据了,返回-1

    3. 缓冲区有数据就从缓冲区中读取 空参的read方法:一次读取一个字节,遇到中文一次读多个字节,把字节解码并转成十进制返回 有参的read方法:把读取字节,解码,强转三步合并了,强转之后的字符放到数组中

flush刷新:刷新之后,还可以继续往文件中写出数据

close关流:断开通道,无法再往文件中写出数据

Java IO流-基本流的评论 (共 条)

分享到微博请遵守国家法律