Java基础Day20

day20

  1. 字节高效缓冲流
    BufferedInputStream和BufferedOutputStream,分别是InputStream和OutputStream的子类
    BufferedInputStream和BufferedOutputStream只是包装类,本身不具备文件的读写功能,将具有读写功能的流做加强,加强成一个高效流,再进行文件内容读取效率高

  2. 高效缓冲流构造方法
    BufferedInputStream(InputStream in) : 将一个字节的输入流加强成一个高效的字节输入流
    BufferedOutputStream(OutputStream out) : 将一个字节的输出流加强成一个高效的字节输出流

  3. 高效缓冲流的工作原理:
    BufferedInputStream类一经创建,类的底层就会开辟一个8192个字节大小的数组,调用read方法进行文件内容读取时,一次性的从文件中读取8192个字节,将读取到的字节数,装到底层的字节数组中,以后再调用read方法时,从数组中获取文件内容,如果8192字节都读取完毕,再调用read方法,还是从文件中在读取8192个字节,直至文件读完. 实现高效. IO流工作效率低原因就在于频繁与磁盘文件进行交互,而高效缓冲流减少了与磁盘的交互

BufferedOutputStream类一经创建,类的底层就会开辟一个8192个字节大小的数组,每次使用write向文件中写入内容,不是直接向文件中写,先写入创建的8192大小的数组中,如果写满了,那么一次性将8192个字节一起写入到文件中,如果没写满,那么当关闭流资源时,将所有的数组中的内容同步到文件中. 高效原因也是减少与磁盘的交互

代码
package com.zgjy.stream;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class BufferedStreamDemo {

public static void main(String[] args) throws IOException{
	long start = System.currentTimeMillis();
	// 1. 确定从哪里读取文件,将文件封装在一个输入流中
	FileInputStream fis = new FileInputStream("D:\\0826Java系统班\\day20\\视频\\01.day19内容回顾.wmv");
	// 2.使用高效字节缓冲流进行文件的读取
	BufferedInputStream bis = new BufferedInputStream(fis);
	// 3.确定将视频复制到D:\\day19.wmv
	FileOutputStream fos = new FileOutputStream("D:\\day19.wmv");
	// 4.使用高效字节缓冲流写入文件
	BufferedOutputStream bos = new BufferedOutputStream(fos);
	// 5. 文件复制,边读边写
	byte[] b = new byte[1024];
	int len;
	while((len = bis.read(b)) != -1) {
		bos.write(b,0,len);
	}
	
	// 6. 关闭资源
	bos.close();
	bis.close();
	
	long end = System.currentTimeMillis();
	System.out.println(end-start);
}

}

  1. 字符流
    可以直接对字符进行操作的流,称为字符流
    字符的输入流 Reader : 读取文件中内容
    字符的输出流 Writer : 向文件中写入内容

2.1 字节流读取中文乱码问题
字节流读取中文文件,读取出的内容乱码
原因 : 一个中文占有2个字节,每次读取一个字节,将中文拆分开了
将每一个拆分出的字节转换成字符,结果无法匹配出正确的字符,于是出现了乱码
解决方案: 如果可能每次读取一个字符,就可以避免中文被拆分的问题

代码
package com.zgjy.stream;

import java.io.FileInputStream;
import java.io.IOException;
public class FileInputReadTxt {
public static void main(String[] args) throws IOException{
FileInputStream fis = new FileInputStream(“D:\new.txt”);
int len ;
// 字节流读取中文文件,读取出的内容乱码
// 原因 : 一个中文占有2个字节,每次读取一个字节,将中文拆分开了
// 将每一个拆分出的字节转换成字符,结果无法匹配出正确的字符
// ? 就表示不知道,于是出现了乱码
while((len = fis.read()) != -1) {
System.out.print((char)len+" ");
}
fis.close();
}
}

2.2 字符输入流Reader
Reader : 字符输入流,是一个抽象类,来自java.io包,需要找有个子类FileReader
FileReader 来自于java.io包,使用字符进行文件的读取,使用系统的默认编码表进行字符读取

FileReader的构造方法:

  1. FileReader(File f) : 从File所表示的文件中读取内容

  2. FileReader(String path) : 从String所表示的文件中读取内容

  3. read() : 每次读取一个字符,返回值int类型, 返回值为字符在默认的编码表中对应的数字,如果读到-1,证明文件读取结束

  4. read(char[] ch) : 每次最多读取ch长度的字符,将读取到的字符放置到ch数组中,返回值类型int类型,表示读取到的字符的个数,如果读到-1,证明文件读取结束

代码
package com.zgjy.stream;
import java.io.FileReader;
import java.io.IOException;
public class FileReaderDemo {

public static void main(String[] args) throws IOException{
	// 1. 创建一个字符的输入流,用于使用字符读取new.txt文件中的内容
	FileReader fr = new FileReader("D:\\new.txt");
	// 2. 使用单个字符进行文件读取
	int len;
	/*while((len = fr.read()) != -1) {
		System.out.print((char)len + "  ");
	}*/
	
	// 3. 优化,使用字符数组进行文件内容读取
	char[] ch = new char[4];
	
	while((len = fr.read(ch)) != -1) {
		// 将字符数组转换成字符串
		System.out.print(new String(ch,0,len));
	}
	fr.close();
}

}

2.3字符输出流Writer
Writer : 写入字符的抽象类,来自java.io包,不能实例化对象,需要找到子类FileWriter

  1. FileWriter的构造方法
    1)FileWriter(File f) : 向f所表示的文件中写入字符内容
    2)FileWriter(String path) : 向String字符串所表示的文件中写入字符内容
    注意 : 1) 和 2) 的构造方法,覆盖源文件写入内容
  1. FileWriter(File f,boolean append):向f所表示的文件中写入追加字符内容
  2. FileWriter(String path,boolean append):向String字符串所表示的文件中追加写入字符内容
  1. FileWriter向文件中写入字符的方法
  1. write(int c) : 向文件中写入单个字符,int类型参数就是字符对应的int类型编码值
  2. write(char[] ch) : 向文件中写入字符数组ch
  3. write(char[] ch ,int index ,int length): 向文件中写入字符数组ch的一部分,从index索引位置开始写,写入length个长度
  4. write(String s): 将字符串写入到文件中

代码
package com.zgjy.stream;
import java.io.FileWriter;
import java.io.IOException;
public class FileWriterDemo {
public static void main(String[] args) throws IOException{
// 1. 创建一个FileWriter对象,项文件中写入字符
FileWriter fw = new FileWriter(“a.txt”);
// 2. 向文件中写入单个字符write()
//aA1进步1进今天是星期二
fw.write(97);// a
// 3. 向文件中写入字符数组 write(char[] ch)
char[] ch = {‘A’,‘1’,‘进’,‘步’};
fw.write(ch);
//4. 写字符数组的一部分write(char[] ch ,int index , int length)
fw.write(ch, 1, 2);//‘1’,‘进’
//5. 写入字符串 write(String s)
fw.write(“今天是星期二”);

	fw.close();
}

}

2.4close()与flush()方法的区别

  1. 问题: 使用FileWrite向文件中写入内容,最终没有关流,发现文件中没有写入成功?
  2. 原因:
    FileWriter底层也有一个数组缓冲,1024大小的字符数组,于是向文件中写入内容,先写入到字符数组中,当字符数组写满,自动将1024个字符一次性同步到文件中; 没有写满也没有关流,数据存在于数组缓冲中,没有同步到文件中
  3. 解决方案:
    flush() : 刷新流的缓冲,将数组缓冲中的数据刷新到文件中,flush之后的流资源可以继续使用
    close() : 表示流资源的关闭,在进行流资关闭之前,close方法会先调用flush刷新功能,将存在与数组缓冲区中的所有内容刷新到文件中,然后再关闭流资源,关闭资源后,流不能再继续使用

注意 : 使用流资源结束后,一定要关闭资源close();

代码
package com.zgjy.stream;
import java.io.FileWriter;
import java.io.IOException;
public class FileWriterDemo {
public static void main(String[] args) throws IOException{
// 1. 创建一个FileWriter对象,项文件中写入字符
FileWriter fw = new FileWriter(“b.txt”);
// 2. 向文件中写入单个字符write()
//aA1进步1进今天是星期二
fw.write(97);// a
// 3. 向文件中写入字符数组 write(char[] ch)
char[] ch = {‘A’,‘1’,‘进’,‘步’};
fw.write(ch);
// 刷新数组缓冲区中的数据到文件中
fw.flush();
//4. 写字符数组的一部分write(char[] ch ,int index , int length)
fw.write(ch, 1, 2);//‘1’,‘进’
//5. 写入字符串 write(String s)
fw.write(“今天是星期二”);
fw.close();
// fw.write(“周后的”); 关闭流资源后.流不能继续使用
}
}

2.5字符流进行纯文本文件复制
文件复制: 边读边写
什么叫纯文本文件 : 使用txt打开文件,并且人类可以读懂这样的文件,可以成为纯文本文件

字符流可以复制纯文本文件,但是不建议时候字符流进行文件的复制
在这里插入图片描述

代码
package com.zgjy.stream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

// 复制文本文件a.txt,可以复制,性能不好
public class ReaderCopy {
public static void main(String[] args) throws IOException{
// 1. 确定数据源,从哪个文件中复制内容
FileReader fr = new FileReader(“a.txt”);
// 2. 绑定一个数据目的,将内容复制到哪里
FileWriter fw = new FileWriter(“copy.txt”);
// 3.通过字符数组进行文件复制,可以提高效率
char[] ch = new char[100];
int len;
// 从文件中读取字符数据
while((len = fr.read(ch)) != -1) {
// 将读到的字符写入到copy.txt中
fw.write(ch, 0, len);
}
fw.close();
fr.close();
}
}

2.6字符流进行非文本文件复制
字符流不能进行非文本文件的复制
问什么:(举例图片复制)

  1. 字符流从图片中读取字节,读取到字节,直接将字节通过编码表转换成字符,但是类似图片,视频中的字节是无法通过编码变转换成合适的字符的,于是,既然不能转,那就是用?替代,那么目标文件中,不是正确的图片或者是视频的字节组成,于是复制,失败了,目标文件损坏的

结论: 什么场景下可以使用字符流

  1. 如果读取带有中文的文本,并且,一边读取一遍查看文件内容,建议使用字符流
  2. 任何形式的文件复制,都使用字节流进行复制

代码
package com.zgjy.stream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

public class ReaderCpoyPicture {
// 字符流不能进行非文本文件的复制
public static void main(String[] args) throws IOException{
// 1. 确定数据源,从哪个文件中复制内容
FileReader fr = new FileReader(“D:\0826Java系统班\day09\图解\单继承.png”);
// 2. 绑定一个数据目的,将内容复制到哪里
FileWriter fw = new FileWriter(“D:\picture.png”);
// 3. 边读边写
char[] ch = new char[100];
int len ;
// 字符流复制的图片时损坏的
while((len = fr.read(ch)) != -1) {
fw.write(ch,0,len);
}
fw.close();
fr.close();
}
}

2.7字符高效缓冲流
BufferedReader : 字符高效缓冲输入流,Reader的子类
BufferedWriter : 字符高效缓冲输出流,Writer的子类

  1. 构造方法:
    BufferedReader(Reader r) : 将一个字符输入流加强成高效的字符输入流,实现单个字符,字符数组以及行的读写
    BufferedWriter(Writer w) : 将一个字符输出流加强成高效的字符输出流,实现单个字符,字符数组以及行的读写

  2. 高效原理
    BufferedReader创建时,类的底层会创建一个8192个大小的字符数组,每次调用read方法,从文件中读取8192个字符,接下来每次调用read方法,都是从底层的数组中读取文件内容,如果8192个字符读取完毕,在调用read方法时,继续从文件中读取8192个字符,直到文件读取完毕,因为减少了与磁盘的交互,因此性能比较高

BufferedWriter创建时,类的底层会创建一个8192个大小的字符数组,每次调用write方法,都将字符写入到数组中,当写满8192个字符,数组自动将所有字符同步到文件中,如果没有写满8192个字符,可以通过flush和close方法,将数据同步到文件中

代码
package com.zgjy.stream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

// 使用高效的字符缓冲流进行纯文本文件的赋值
public class BufferedReaderCopy {

public static void main(String[] args) throws IOException{
	// 1. 确定源文件
	BufferedReader br = new BufferedReader(new FileReader("a.txt"));
	// 2.确定目标文件
	BufferedWriter bw = new BufferedWriter(new FileWriter("bufferedCpoy.txt"));
	// 3. 复制文件内容,字符数组
	char[] ch = new char[6];
	int len;
	while( (len = br.read(ch)) != -1) {
		bw.write(ch,0,len);
	}
	bw.close();
	br.close();
}

}

2.8字符高效缓冲流的特有方法
BufferedReader : 特有方法
readLine() :每次从文件中读取一行内容(以回车换行为一行的标准),返回值类型String类型,如果读到文件的末尾,返回null字符串

BufferedWriter : 特有方法
newLine() :表示向文件中写入一个回车换行,没有返回值

代码
package com.zgjy.stream;
import java.io.FileInputStream;
import java.io.IOException;
public class FileInputReadTxt {

public static void main(String[] args) throws IOException{
	FileInputStream fis = new FileInputStream("D:\\new.txt");
	int len ;
	// 字节流读取中文文件,读取出的内容乱码
	// 原因 : 一个中文占有2个字节,每次读取一个字节,将中文拆分开了
	// 将每一个拆分出的字节转换成字符,结果无法匹配出正确的字符
	// ? 就表示不知道,于是出现了乱码
	while((len = fis.read()) != -1) {
		System.out.print((char)len+"  ");
	}
	fis.close();
}

}

  1. 转换流
    GBK: 国标码,中国标准编码表,包含ASCII,包含中文,GBK也是操作系统默认编码表,数字和字母,占有一个字节大小,中文占有两个字节
    UTF-8 : 万国码表,全世界的标准码表,包含ASCII,包含其他国家的语言码表,数字和字母,占有一个字节,中文占有三个字节

为什么需要转换流:
原因 : 相同的文件内容,因为编码表不一样,那么文件大小不一致
举例 : 你好---->存储在UTF-8的文本中,占有6字节
你好—>存储在GBK文本中,占有4字节
于是,不同的编码集,进行文件复制时,可能会出现乱码

InputStreamReader : 输入转换流,将字节以指定的编码集转换成字符,字节流到字符流的桥梁
OutputStreamWriter : 输出转换流,将一个字符使用指定的编码集转换成对应的字节,字符到字节的桥梁

  1. 转换流的构造方法
    InputStreamReader (InputStream in , String characterSet) : 表示从in所表示的字节输入流中读取内容, 将内容使用指定的characterSet编码集,转换成对应的字符
    OutputStreamWriter(OutputStream out,String characterSet) : 表示通过out字节的输出流写,获取到的是字符的信息,将字符信息通过指定的编码集characterSet,转换成对应的字节

转换流的工作原理:
在这里插入图片描述

代码
package com.zgjy.stream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
public class ZhuanHuanStream {
public static void main(String[] args) throws IOException{
//copy1();
copyRight();
}

// 普通流进行复制
public static void copy1() throws IOException{
	FileInputStream fis = new FileInputStream("UTF-8.txt");
	FileOutputStream  fos = new FileOutputStream("GBK.txt");
	int len;
	while((len = fis.read()) != -1) {
		fos.write(len);
	}
	fos.close();
	fis.close();
}
// 使用转换流复制不同编码集文件
public static void copyRight()  throws IOException{
	// 1. 确定从哪里读取文件
	FileInputStream fis = new FileInputStream("UTF-8.txt");
	InputStreamReader isr = new InputStreamReader(fis, "UTF-8");
	// 2.确定向哪里写文件
	FileOutputStream  fos = new FileOutputStream("GBK.txt");
	OutputStreamWriter osw = new OutputStreamWriter(fos, "GBK");
	// 3. 复制文件
	int len;
	while((len = isr.read()) != -1) {
		osw.write(len);
	}
	osw.close();
	isr.close();
}

}

  1. Debug测试
    测试(调试) : 将字节写的代码的主要功能实现出来
    个人代码测试使用场景 : 代码运行没有错,但是结果不对
    Debug测试 : 主要功能就是不让代码一次性都执行完,可以让你的代码停在指定的位置,剩下代码可以一行一行执行,在执行过程中,你可以查看每一行代码的结果

如何进行Debug测试:

  1. 需要设置代码的断点,代码停止的位置,就叫做断点 breakpoint
    断点必须要设置在有效的代码行
  2. 进入Debug运行模式

进入denug之后的界面

在这里插入图片描述

使用下图中的F5或者F6控制代码的运行
Step Into (F5 ): 表示进入到当前代码行内部查看,一般是用于循环和查看方法
Step Over(F6): 表示直接将当前行直接完毕
在这里插入图片描述

  1. Java命名规范总结
  2. 包命名: 公司域名的倒写 com.zgjy.包名(一般都是小写)
  3. 类命名: 类的名字首字母大写,如果类名中有多个单词,那么每个单词的首字母都大写
  4. 方法命名: 首字母小写,如果有多个单词,从第二个单词开始首字母大写
  5. 变量命名: 首字母小写,如果有多个单词,从第二个单词开始首字母大写
  6. 常量命名: 使用final修饰的变量称为常量, 全大写,如果有多个单词,单词之间使用_分开
    举例: CUST_AGE
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值