Java核心语法——IO流
文章目录
- IO流
- 概述
- 简述
- 分类
- 步骤
- 字节流
- InputStream
- FileInputStream
- 概述
- 构造方法
- OutputStream
- FileOutputStream
- 构造方法
- 字节流文件拷贝
- 普通的
- 高效缓冲字符流
- 字符流
- 概述
- Reader
- FileReader
- Writer
- FileWriter
- 构造方法
- 字符流文件拷贝
- 普通的
- 高效缓冲字符流
- 选择字节流、字符流
- 转换流
- 编码表
- 转换流
- 练习
- 疑惑
IO流
概述
简述
I\O:input、output。输入输出都是针对内存而言
input:输入,其他设备到内存
output:输出,内存到其他设备
什么是I\O流?
1)I\O就是设备之间进行数据交互的对象所属的类型
2)Java中操作设备之间数据传输的对象,都是IO流对象,这些对象所属的类型,都在io包中
分类
按照共能分为:
字节流:直接操作字节的流对象
字符流:直接操作字符的流对象
按照流向分为:
输入流:其他设备流到内存
输出流:内存流到其他设备
所以有四个顶层抽象类
字节流:字节输入流:InputStream字节输出流:OutputStream
字符流:字符输入流:Reader字符输出流:Writer
PS:根据不同的交互设备,有不同的具体子类,但是没必要那么详细,直接使用对应的顶层抽象类即可(向上转型)
步骤
1)导包导入io包
2)处理解决异常
3)关闭io流对象
字节流
计算机最小存储单位是字节,那么字节可以表示任意类型
字节流:
字节输入流:InputStream
字节输出流:OutputStream
InputStream
字节输入流的顶层抽象父类。因为其中的read()方法是抽象方法(不知道具体的交互设备),那么对应的类就是抽象类。
注意: InputStream是一个抽象类,那么创建对象时,使用用子类创建
方法
int read()从当前字节输入流中,读取并返回一个字节,未读到返回-1
注意既然是字节,为什么是int类型?因为字节不能表示负数,无法指名没有读到字节的情况,所以,将字节前面加24个0,变成intint read(byte[] arr)从当前字节输入流中,读取并存放在arr中,未读到返回-1。
注意连续使用时,会接着上次的内容继续读取并存放int available()剩余未读的字节个数
void close()4
FileInputStream
概述
InputStream具体的子类,最常用的,与磁盘交互
不仅一次可以读取一个字节,一次也可以读取很多字节
因为一切数据在计算机中都是以字节存储,所以FileInputStream可以读取任意文件,包括图片、视频、音频
构造方法
FileInputStream(File f)将file对象封装成字节输入流,将来可以读取文件的信息
FileInputStream(String path)将字符串(文件路径)封装成字节输入流,将来可以读取信息
注意:封装的文件对象都是针对文件本身而言,不是封装路径
FileInputStream f = new FileInputStream("a.txt");byte[] arr = new byte[2];int length;while((length = f.read(arr)) != -1) {//第一次读取两个字节,并存放在arr中,arr{1,2}//第二次读取一个字节,并存放在arr中,arr{3,2},覆盖掉原本的0索引上的元素//第三次没有读取到字节,返回-1,并结束循环System.out.print(new String(arr,0,length) + "\t");System.out.println(f.available());}f.close();
FileInputStream fis = new FileInputStream("D:\\www\\baidu\\test.txt");int a;while((a = fis.read()) != -1) {System.out.println(a);}
OutputStream
字节输出流的顶层抽象父类
注意: OutputStream是一个抽象类(不知道关联的具体的设备是什么),那么创建对象时,使用用子类创建
方法
void write(int b)
注意因为是字节流,而存储的又是int类型,所以存储时会将前三个字节(全是0)取消,只存后一个字节的内容
void write(byte[] arr)
void write(byte[] arr,int offest,int len)offest:索引开始的位置len:总共输出多少位
void close()
FileOutputStream
OutputStream具体的子类,最常用的,与磁盘交互
构造方法
FileOutputStream(String path)
FileOutputStream(File f)1)指定的路径不存在的,创建该文件2)指定的路径是存在的,清空该文件FileOutputStream(String path, boolean append)
FileOutputStream(File f, boolean append)1)指定的路径不存在,自动创建2)指定的路径存在,且append设置为true,则不会清空该文件,而是在后面追加
FileOutputStream fos = new FileOutputStream("test.txt", true); //原内容为123byte[] arr = {65, 66, 67};fos.write(arr, 0, 2);//123ABfos.close();
字节流文件拷贝
普通的
一、低效率,使用内存少
一个字节一个字节的拷贝
FileInputStream fis = new FileInputStream("a.txt");
FileOutputStream fos = new FileOutputStream("a_copy.txt");
int a = 0;//用于判断是否还有没读完的字节
while((a = fis.read()) != -1) {fos.write(a);
}fis.close();
fos.close();
二、高效率,连续占用的内存大,不贴近实际
使用一个数组一次拷贝
FileInputStream fis = new FileInputStream("a.txt");
FileOutputStream fos = new FileOutputStream("a_copy_arr.txt");
byte[] arr = new byte[fis.available()];
fis.read(arr);
fos.write(arr);fis.close();
fos.close();
三、高效率,连续占用的内存较小,贴近实际
使用一个数组多次拷贝
FileInputStream fis = new FileInputStream("a.txt");
FileOutputStream fos = new FileOutputStream("a_copy_arrs.txt");
byte[] arr = new byte[1024 * 8];
int len = 0;
while((len = fis.read(arr)) != -1) {fos.write(arr, 0, len);
}
fis.close();
fos.close();
高效缓冲字符流
加强普通的输入流、输出流,只是起一个加强作用,使用方式不变
构造方法
BufferedInputStream(字节输入流对象)
BufferedOutputStream(字节输出流对象)
FileInputStream fis = new FileInputStream("a.txt");
FileOutputStream fos = new FileOutputStream("a_buffer.txt");BufferedInputStream bis = new BufferedInputStream(fis);
BufferedOutputStream bos = new BufferedOutputStream(fos);
int a =0;
while((a = bis.read()) != -1) {bos.write(a);
}bis.close();
bos.close();
高效原因?
BufferedInputStream 1)该类型底层准备了一个大小为8*1024大小的数组,调用者使用read()读取一个字节时,该对象一次读取8192个字节。2)将第一个字节返回给调用者,调用者第2次~第8192次再调用时,就不用去磁盘取数据了,直接从该数组取字节就好。3)当8192个字节读取完之后还需要取数据时,又在磁盘中挨着上次的8192个字节继续取数据即可BufferedOutputStream 1)当使用write()方法写出字节数据时,先将写出的数据存储在自己的数组中(8*1024个字节大小),当写出够8192字节数据时,一起刷新2)如果没写出够8192个字节时,关闭流之前刷新缓冲:底层有1204*8字节大小的数组,存储每次输入和输出的字节内容刷新:将缓冲区中的数据,写进磁盘中
特有方法
flush(),刷新(将缓冲区中的数据,写进磁盘中)bos.write(b);bos.flush();bos.close();
字符流
概述
字符类底层就是字节流。加强了字节流。因为每次读、写时,不知道到底需要读、写几个字节(因为可能存在汉字、英文等夹杂着的情况),所以加强字节流,变为字符流。
所以
如果要表示中就需要连续读取两个字节,表示英文又只需要读取一个字节。
而
由于关联的具体设备位置,所以定义的也是抽象类。
PS:GBK编码表中,如果读取的字节是正数,那么就是英文;如果读取的第一个字节是负数,那么就是中文(中文由两个字节表示)
Reader
字符输入流的顶层抽象类
注意: Reader是一个抽象类,那么创建对象时,使用用子类创建
方法
int read())从当前字节输入流中,读取并返回一个字节,未读到返回-1
注意既然是字符,为什么是int类型?因为字符不能表示负数,无法指名没有读到字节的情况,所以,将字符前面加16个0,变成int
int read(char[] arr)
void close()
FileReader
Reader的子类,最常用的,与磁盘交互
构造方法
FileReader(File f)
FileReader(String path)指定路径的文件,封装为字符输入流
FileReader r = new FileReader("b.txt");//因为要表示没读到字符的状态,而char不能表示负数,所以定义int(前两个字节用0填充),-1表示没读到int a = 0;while((a = r.read()) != -1) {//read返回的是int类型的,所以需要转型System.out.print((char)a + " ");}
Writer
字符输出流的顶层抽象类
方法
write(int c)
write(char[] chs)
write(char[] chs, int offset, int len)从offset索引开始,共len个字符写出到指定文件write(String str)将字符串编码形成字节数组之后,写出到目标文件去write(String str, int offset, int len)
FileWriter
Writer的子类,最常用的,与磁盘交互
构造方法
FileWriter(String path)
FileWrtier(File f)1)指定的路径不存在的,创建该文件2)指定的路径是存在的,清空该文件FileWriter(String path, boolean append)
FileWriter(File f, boolean append)1)指定的路径不存在,自动创建2)指定的路径存在,且append设置为true,则不会清空该文件,而是在后面追加
FileWriter fw = new FileWriter("crush.txt");String str = "好久不见";fw.write(str, 0, 2);fw.close();
字符流文件拷贝
字符输入流
字节——》GBK,GBK——》Unicode,Unicode——》int
字符输出流
与字符输入流相反
普通的
FileReader fr = new FileReader("c.txt");FileWriter fw = new FileWriter("c_copy.txt");int c;//每次读取到的字符while ((c = fr.read()) != -1) {fw.write(c);}fr.close();fw.close();
高效缓冲字符流
加强普通的输入流、输出流,只是起一个加强作用,使用方式不变
构造方法
BufferedReader(Reader r)
BufferedWriter(Writer w)
特有方法
1)BufferedReader
String readLine(),读取一整行,不包括换行符。返回null,表示没有可读的内容
注意:以换行符为每一次读取的结束符2)BufferedWriter
newLine(),可以提供一个跨平台的换行符windows中为\r\n;linux中为\n
public static void main(String[] args) throws IOException {BufferedReader br = new BufferedReader(new FileReader("demo.java"));BufferedWriter bw = new BufferedWriter(new FileWriter("demo_copy.java"));String a;while((a = br.readLine()) != null) {//读取一整行,没有下一行,返回null
// System.out.println(a);bw.write(a);bw.newLine();//换行}br.close();bw.close();}
高效的原因同字节流一样
选择字节流、字符流
1)文件拷贝,最好使用高效缓冲字节流。因为字符类拷贝时,涉及很多操作,反而变慢了
2)关于字符的操作(除文件拷贝),使用字符流
转换流
编码表
字符集
含义:在字节和字符之间,相互转换时,查询的对应关系,就是编码表
常见编码表:GBK:定义了中文和英文的各种字符,一个英文使用一个字节表示,一个中文使用两个字节表示UTF-8:万国码提升形式,一个英文使用一个字节表示,一个中文使用三个字节表示
说明:一般在java的内存中,使用的编码都是Unicode编码,因为java中的字符都使用两个字节来表示在java的内存以外,会使用其他的编码形式,具体使用哪种,取决于文件的要求
转换流
就是将字节流包装成了字符流对象,可以直接操作字符
Reader 字符输入流的顶层抽象父类InputStreamReader 能自主确定解码形式的字符输入流构造方法InputStreamReader(InputStream is)将指定的字节流转成字符流,按照平台默认编码表解码InputStreamReader(InputStream is, String charSetName)当前转换流,按照指定的字符集来解码FileReader 使用平台默认解码的操作文件的字符输入流Writer 字符输出流的顶层抽象父类OutputStreamWriter 能自主确定编码形式的字符输出流构造方法OutputStreamWriter(OutputStream os)将指定的字节输出流转换成字符输出流,按照平台默认编码表编码OutputStreamWriter(OutputStream os, String charSetName)当前转换流,按照指定的字符集来编码FileWriter 使用平台默认编码的操作文件的字符输出流
一、输入流关联键盘
InputStream is = System.in;InputStreamReader isr = new InputStreamReader(is);BufferedReader br = new BufferedReader(isr);System.out.println(br.readLine());
二、将一个uft8编码的文件内容,拷贝到一个gbk编码的文件中(eclipse中默认的编码表是Unicode,但是打开txt文本时,使用的编辑器默认是GBk解码的)
private static void test_utf8_copy_gbk() throws IOException {// InputStream is = new FileInputStream("gbk_utf8.txt");
// InputStreamReader fr = new InputStreamReader(is,"utf8");
// OutputStream fw = new FileOutputStream("gbk_utf8_copy.txt");
// OutputStreamWriter osw = new OutputStreamWriter(fw);InputStreamReader isr = new InputStreamReader(new FileInputStream("gbk_utf8.txt"),"utf8");FileWriter fw = new FileWriter("gbk_utf8_copy.txt");int a;while((a = isr.read()) != -1) {fw.write(a);}isr.close();fw.close();}
三、将一个gbk编码的文件的内容,拷贝到一个utf8编码的文件中(eclipse中默认的编码表是Unicode,但是打开txt文本时,使用的编辑器默认是GBk解码的)
public static void gbk_copy_utf8() throws IOException {//解码格式为GBK可以不写???FileReader fr = new FileReader("gbk_utf8_copy.txt");OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("gbk_utf8.txt"), "utf8");int a;while((a = fr.read()) != -1) {osw.write(a);}fr.close();osw.close();}
【注意】
一、读取、写出格式
读取时,解码格式必须和源文件的编码格式相同
写出时,编码格式必须和目标文件的编码格式相同
二、编码和解码
将字符转换为字节的方式称为编码(A——》65)
将字节转换为字符的方式称为解码(65——》A)
练习
疑惑
1、既然eclipse中文本默认是GBK编码,而java代码默认是Unicode编码,那么将GBK编码的文本拷贝到UTF8编码的文本时,读取中英文汉字混合的情况的时候为何没有乱码???
猜测
GBK——》Unicode
英文:1个字节——》2个字节,前面加8个0
汉字:2个字节——》2个字节
Unicode——》UTF8
英文:2个字节——》1个字节,去掉8个0
汉字:2个字节——》3个字节,前面加8个0
2、格式为GBK可以不写???
FileReader fr = new FileReader(“gbk_utf8_copy.txt”);
FileWriter fw = new FileWriter(“gbk_utf8_copy.txt”);
3、编码是字符变字节,为何读取时叫解码;写出时叫编码???
Java核心语法——IO流相关推荐
- JAVA核心知识点--IO流
目录 一.JavaIO流的分类 输入流和输出流 字节流和字符流 节点流和处理流 二.InputStream,OutputStream,Reader和Writer 三.节点流 四.处理流 缓冲流 转换流 ...
- java中的IO流(超全)(超详解)结合实例轻松掌握
java进阶之IO流 IO流的概念(大纲): 1.InputStream和OutputStream的继承关系图 2.Reader和Writer的继承关系图 3.文件专属流(加※为重点掌握) ※File ...
- java io流分为,Java中的IO流按照传输数据不同,可分为和
Java中的IO流按照传输数据不同,可分为和 答:字节流 字符流 克里斯蒂安 · 麦茨指出:想象的能指就是电影的能指,作为象征的科学,在第三视野范围内的解读,它是( ) 答:建立在共同的永久的背景之中 ...
- 重新java系列之IO流
重新java系列之IO流 内容介绍 学习目标 字符输入流 字符输入流[Reader] FileReader类 构造方法 读取字符数据 使用演示: 字符输出流 字符输出流[Writer] FileWri ...
- 猿创征文|Java中的IO流大家族 (两万字详解)
目录 IO流 概述 分类 四大家族 需要掌握的16个流 文件专属 FileInputstream(读 字节) FileInputStream类的其他常用方法 FileOutputStream (写 字 ...
- 视频教程-极简Java五:IO流-Java
极简Java五:IO流 华中科技大学毕业,十余年行业经验,曾带领团队完成CPN客户管理系统,并完成农业银行网站,乐途旅游网等网站的开发,在Java领域有深厚的积累,授课风格深入浅出,直指核心. 夏昊 ...
- 笔记整理2----Java语言基础(二)06 断点调试与数据加密+07 面向对象-类与对象+08 java常用API-基础+09 java集合+10 IO流-基础
06 断点调试与数据加密+07 面向对象-类与对象+08 java常用API-基础+09 java集合+10 IO流-基础 第06天 java基础语法 今日内容介绍 Eclipse断点调试 基 ...
- java中io流实现哪个接口_第55节:Java当中的IO流-时间api(下)-上
标题图 Java当中的IO流(下)-上日期和时间日期类:java.util.Date 系统时间:long time = System.currentTimeMillis();public class ...
- Java中的IO流(六)
上一篇<Java中的IO流(五)>把流中的打印流PrintStream,PrintWriter,序列流SequenceInputStream以及结合之前所记录的知识点完成了文件的切割与文件 ...
最新文章
- 《百面机器学习》---AI算法工程师求职必备“面经”
- Linux - 网络相关指令
- likelihood(似然) and likelihood function(似然函数)
- Python高级特性:切片
- python程序中断时,输出打印日志
- vc++ List Control控件获得所有选中行的序号
- Centos 7.3 搭建php7,mysql5.7,nginx1.10.1,redis
- vue router 懒加载实现
- Klevgrand DAW Cassette for Mac(磁带模拟效果器插件)
- 中债估值 收益率_收债
- ROS的激光雷达、 加速度计、 陀螺仪传感器
- 4.4.4系统不用ROOT激活xposed框架流程
- 台式计算机有线无线网卡设置,台式电脑怎么设置无线网络,详细教您台式电脑怎么设置无线网络...
- HTML+CSS+JS实现 ❤️3D立体魔方小游戏❤️
- 微信小程序加载图片报错
- 液滴模板水凝胶的温度控制形状变化(定制PNIPA/膨润土复合水凝胶/聚乙烯醇/魔芋胶复合凝胶/海藻酸钠(SA)/氧化石墨烯(GO)复合水凝胶/壳聚糖(CS)-g-PAM/氧化石墨烯(GO)复合水凝胶)
- stringstream切割字符串
- 单点遥信发送表里一般都有什么变量啊?
- 光源类型-CIE标准光源
- 好机会!IT工程师恭喜了!纳入工信部-工业互联网人才库!8月31日报名截止