IO流,字节流的4种读写方式,字符流的5种读写方式

1.1 IO流分类
按照数据的流向:输入流:读数据
输出流:写数据
按照数据类型来分:字节流:字节输入流,字节输出流
字符流:字符输入流,字节输出流
两种流使用情况:如果数据通过windows自带的记事本可以打开,可以读懂文件里的内容,就是用字符流,否则使用字节流,如果你不知道使用哪种类型的流,就使用字节流

1.2 字节流
1.2.1 字节流写数据
字节流抽象基类
InputStream:这个抽象类表示字节输入流的所有类的超类
OutputStream:这个抽象类是表示字节输出流的所有类的超类
子类名特点:子类名称都是以其父类名作为子类的后缀

FileOutputStream//文件输出流用于数据写入Flie
FileOutputStream(String name)//创建文件输出流以指定的名称写入文件

该方法调用系统的功能创建文件;
创建字节流输出对象;
让字节流输出对象指向创建好的文件

步骤:创建输出流对象,调用字节流对象的写数据方法,释放资源
写数据的方式:

void write(int b);
void write(byte[] b)
void write(byte[] b,int off,int len)

1.2.2 字节流写数据的两个问题
字节流数据如何实现换行
写完数据加一个换行符号,fos.write(“\r\n”.getBytes())

Window:\r\n
Linux:\n
Mac:\r

字节流写数据如何实现追加写入呢?
保存上一次写入文件的数据,再次运行时,保存了上次结果,并加入新运行的结果;

public FileOutputStream(String name,boolean append)//如果第二个参数是true,则字节写入文件的末尾而不是开头

1.2.3 字节流写数据加异常处理
finally :在异常处理提供finally来执行清除的操作,比如IO流中释放资源

Try{
	可能出现异常的代码
}catch(异常类名 变量名){
	异常处理代码
}finally{
	执行所有的清除操作
}

1.2.4 字节流读数据(一次读一个字节数据)
FileInputStream(String name):通过打开与实际文件的连接来创建一个FileInputStream,该文件由文件系统中的路径名name命名

创建字节流输入流对象
调用字节流输入对象的读取数据的方法
释放资源

FileInputStream fis = new FileInputStream(“xxx.txt”);
int by;
while((by = fis.read())!= -1){
System.out.print((char) by);//**可以读取文件换行内容的**
}
fis.close();

read方法是可以读取换行符的。
以上实际工作步骤:
读数据----把读取的数据赋值给by----判断读取到的数据是否为-1

字节流读取一个字节数据为什么要用int类型接收?
字节的取值范围为-128-127。如果文件中有-1,如果按字节返回,则返回-1,读取结束,因此我们需要把读取的字节强转成int类型,高位补0,这样就可以保证所有数为正数,就可以用-1表示末尾

案例:复制文本文件

1.2.5 字节流读数据(一次读一个字节数组的数据)

读取字节数组,如 hello world
实际上,读取的是hello\r\n,和world\r\n

byte[] bys = new byte[1024];//1024的整数倍
int len;
while(len = fis.read(bys) != -1){
System.out.println(new String(bys,0,len));
}
fis.close();

案例:复制图片

1.2.6 字节缓冲流
BufferedOutputStream:该类实现缓冲输出流,通过设置这样的输出流,应用程序可以向底层输出流写入字节,而不为写入的每个字节调用底层系统的调用
BufferedInputStream:BufferedInputStream将创建一个内部缓冲区数组,当从流中读取或跳过字节时,内部缓冲区将根据需要从所包含的输入流中重新填充,一次很多字节
构造方法:
字节缓冲输出流:BufferedOutputStream(OutputStream os)//底层封装了一个大小为8192的数组
字节缓冲输入流:BufferedInputStream(InputStream is)// 底层封装了一个大小为8192的数组
(读有两种方式,跟字节输入流差不多,流的操作都要close,释放资源)
为什么构造方法需要的是字节流,而不是具体的文件或者路径呢?
字节缓冲流仅仅提供缓冲区,而真正的读写数据还得依靠基本的字节流对象进行操作

案例:复制视频
四种方式实现复制视频,并记录每种方式复制视频的时间

基本字节流一次读写一个字节数据
基本字节流一次读写一个字节数组
字节缓冲流一次读写一个字节数据
字节缓冲流一次读写一个字节数组

1.3 字符流
一个汉字存储:GBK编码,占用2个字节;UTF-8编码,占用3个字节。他们俩转化为字节数组时,第一个字节元素是复数.
字节流读汉字时(在控制台输出)出现乱码,因此出现了字符流,字节流可以复制任意文本数据
为什么会出现字符流?
由于字节流操作中文不是特别方便,所以java就提供字符流
字符流 = 字节流 + 编码表
用字节流复制文本文件时,文本文件也会有中文,但是没有问题,因为最终底层操作会自动进行字节拼接成中文,如何识别中文呢?
汉字在存储的时候,无论选择哪种编码存储,第一个字节都是负数
1.3.1 编码表
ASCII字符集:使用7位表示一个字符,128个字符;扩展字符集使用8位表示一个字符,共256字符;
GBXXX字符集:一个小于127的字符的意义与原来相同,但两个大于127字符连在一起时,就表示一个汉字,这样大概可以组合了包含7000多个简体汉字
GBK:最常用的中文码表,收录21003个汉字
GB18030
Unicode字符集:表达任意语言的任意字符,最多使用4个字节的数字来表达
UTF-8:编码规则:128个US-ASCII字符,只需要一个字节编码
拉丁文等字符:需要两个字节编码
大部分常用字(含中文),使用三个字节编码
其他极少数使用的Unicode辅助字符,使用四字节编码

1.3.2 字符串中的编码解码问题
编码:

byte[].getBytes();
byte[].getBytes(String charsetName)

解码:

String(byte[] bytes)
String(byte[] bytes,String charsetName)
byte[] bys = s.getBytes(“GBK”);
String ss = new String(bys,”GBK”)

1.3.3 字符流中的编码解码问题
字符抽象基类:
Reader:字符输入流的抽象类
Writer:字符输出流的抽象类
字符流中的编码解码问题的相关的两个类:
InputStreamReader
OutputStreamWriter

OutputStreamWriter osw = new OutputStreamWriter(“xxx.txt”,”GBK”);
osw.write(“中国’);
osw.close();
InputStreamReaderisr = new InputStreamReader(“xxx.txt”,”GBK”);
int ch;
while((ch = isr.read())!=-1){
System.out.print((char) ch);
isr.close();//我们看不懂文件,是因为文件是UTF-8编码,但可以通过控制台看懂
}

1.3.4 字符流写数据的5种方式

write(int c):
write(char[] cbuf)
write(char[] cbuf,int off,int len)
write(String str)
write(String str,int off,int len)
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(“E:\360Downloads\ray\src\ray\xxx.txt”));
osw.write(97);
osw.flush();//仅仅将缓冲区的数据刷,还可以写数据
osw.close();//释放资源的close()调用,一定会刷新一次,把缓冲区的数据刷进去,一旦关闭就不能写了

注意:字符流不能直接写到文件中,而是在缓冲区,需要flush;释放close,一定会把缓冲区的数据刷新一次。二者区别是调用前者还可写数据,后者一旦调用,就不能写了

1.3.5 字符流读数据的2种方式

int read()
int read(char[] cbuf)

案例:复制JAVA文件

方式一:用 OutputStreamWriter和InputStreamReader
方式二:用FileReader(String name), FileWriter(String name)/
//方式二继承方式一的方法

注意:讨论字符流编码解码问题还是用方式一
为什么读取的字符用int类型接收?
char的取值范围为0-65535,选取一个不在这个范围的数标记文件末尾,而返回-1的话需要转化到int类型

1.3.6 字符缓冲流
BufferedWriter:将文本写入字符输出流,缓冲字符,以提供单个字符,数组和字符串的高效写入,可以指定缓冲区的大小,或者可以接受默认大小,默认值足够大,
BufferedReader:将字符输入流读取文本
构造方法:

BufferedWriter(Writer)
BufferedReader(Reader)

案例:复制JAVA文件

1.3.7 字符缓冲流的特有功能

BufferedWriter:
void newline();//
BufferedReader
public String readLine();//读一行文字,结果包含行的内容的字符串,不包括任何行的终止字符,如果流的结尾已经到达,则为null
BufferedWriter bw = new BufferedWriter(new FileWriter(“E:\360Downloads\ray\src\ray\bww.txt”));
for (int i = 0; i < 10; i++) {
	bw.write(“hello” + i);
	bw.newLine();
	bw.flush();
}
bw.close();
BufferedReader br = new BufferedReader(new FileReader(“E:\360Downloads\ray\src\ray\bww.txt”));
//第一种方式,一次只读一行数据
//	String line = br.readLine();
//	System.out.println(line);
//第二种方式,
String line;
while((line = br.readLine()) != null) {
	System.out.println(line);//只读内容,不读换行符号,因此用println
}
br.close()

案例:复制JAVA文件

1.4 IO流小结
读 写
字节流 2种方式 2种方式
字符流 2种方式 2种方式
字节流:

输入:FileInputStream,BufferedInputStream
输出:FileOutputStream,BufferedOutputStream

小结:字节流可以复制任意文件数据,有4种方式一般采用字节流一次读写一个字节数组的方式
字符流:

输入:InputStreamReader(FileReader),BufferedReader,void newline();
输出:OutputStreamWriter(FileWriter),BufferedWriter
String readLine();void write(String line)

特有的方式:一次读一个字符串,一次写一个字符串

小结:字符流只能复制文本数据,有5种方式

第一次写,希望能早日入坑吧~
————————————————
版权声明:本文为CSDN博主「zcc2018」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/zcc2018/article/details/105784931

  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值