day09-字节缓冲流&字符流

一、字节缓冲流
1.缓冲流
就是在普通流上面添加一个大小为8192的数组缓冲区,用来提高效率

2.字节缓冲流的构造方法
	(1)BufferedInputStream​(InputStream in) 创建一个 BufferedInputStream并保存其参数,输入流 in供以后使用。  
	(2)BufferedInputStream​(InputStream in, int size) 创建具有指定缓冲区大小的 BufferedInputStream ,并保存其参数,输入流 in供以后使用。  

	问题1:为什么在构造方法里面传入的InputStream,而不是File对象?
			因为缓冲流仅仅是提供了一个数组缓冲区,真正干活的还是传入的InputStream
	
	问题2:第二个构造方法的参数size是什么意思?
			size就是缓冲流提供的数组的长度

	问题3:为什么我们不需要关闭InputStream这个流?而仅仅关闭了缓冲流
		因为BufferedInputStream缓冲流是对InputStream字节流进行了一层包装,这个时候它们就成了一个整体,当我们把外面的缓冲流关闭的时候,里面的字节流也会跟着被关闭

3.字节缓冲流复制文件的代码
	public class Demo6 {
		public static void main(String[] args) throws IOException {
			FileInputStream fis = new FileInputStream("C:\\Users\\chun\\Desktop\\1.jpg") ;
			BufferedInputStream  bis = new BufferedInputStream(fis);
			BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("day08/mn.jpg"));

			int len;
			byte[] bytes = new byte[1024];
				while ((len=bis.read(bytes))!=-1){
					bos.write(bytes,0,len);
			}

			bos.close();
			bis.close();
		}
	}

//字节流总结
1.字节输入流
*抽象根类:InputStream
具体子类:FileInputStream
*读数据的方法
(1)int read​() 从该输入流读取一个字节的数据

		(2)int read​(byte[] b) 从该输入流读取最多 b.length个字节的数据到一个字节数组。
						
		(3)int read​(byte[] b, int off, int len) 从该输入流读取最多 len个字节的数据到字节数组。
	
2.字节输出流
	*抽象根类:OutputStream
		具体子类:FileOutputStream
	
	*写数据的方法 
		(1)void write​(int b) 将指定的字节写入此文件输出流。  
		(2)void write​(byte[] b) 将 b.length字节从指定的字节数组写入此文件输出流。   
		(3)void write​(byte[] b, int off, int len) 将 len字节从指定的字节数组开始,从偏移量 off开始写入此文件输出流。
			
3.字节缓冲流
	*字节缓冲输入流
			BufferedInputStream
	*字节缓冲输出流
			BufferedOutputStream
				//方法就是字节流的方法
	
4.复制文件的方式
	(1)一次复制一个字节
			
	(2)一次复制一个字节数组

	(3)字节缓冲流一次复制一个字节
		
	(4)字节缓冲流一次复制一个字节数组

字符流
一、字符流的概述
1.为什么会出现字符流? //“中文”
当我们使用字节流去读文件内容的时候,如果文件的内容都是英文时,不会出问题。
但是,如果文件中有中文时,那么就可能出现读到一半的汉字或者三分之一的汉字
当编码表是GBK的时候,那么我们读到的就是一半的汉字
当编码表是UTF-8的时候,那么这个时候读到的就是三分之一的汉字

	2.什么时候会出现乱码?
		第一个:复制带中文的文件   //不会,因为复制仅仅是把文件换了一个位置,里面的内容不会改变,我们也不会去读它
		第二个:读带中文的文件    //会

二、编码表
	1.ASCII码表:所有的码表都兼容ASCII表
		a  ----  97
		A  ----  65
		0  ----  48
		
	2.GBK:在GBK中每个中文占用两个字节
		GBK是我们windows系统的默认编码

	3.UTF-8:在UTF-8中每个中文占用三个字节
		UTF-8使我们以后开发中要使用的编码

三、字符串中的编码和解码问题
	1.编码
		*从现象上看:就是把能看懂的转成看不懂的
		*从本质上看:就是把字符串转成字节数组
		*编码的方法:
		
				//String ---------- > byte[]
			(1)byte[] getBytes​() 使用平台的默认字符(idea开发工具的编码)集将该 String编码为一系列字节,将结果存储到新的字节数组中。  
			(2)byte[] getBytes​(String charsetName) 使用命名的字符集将该 String编码为一系列字节,将结果存储到新的字节数组中。  
				代码实现:
					byte[] bytes1 = "王小二".getBytes();
					byte[] bytes2 = "王小二".getBytes("UTF-8");
					System.out.println(Arrays.toString(bytes1));
					System.out.println(Arrays.toString(bytes2));
		
	2.解码
		*从现象上看:就是把看不懂的转成能看懂的
		*从本质上看:就是把字节数组转成字符串
		*解码的方法:
		
				//byte[] ---------- >  String
			(1)String​(byte[] bytes) 通过使用平台的默认字符集(idea开发工具的编码)解码指定的字节数组来构造新的 String 。  
			(2)String​(byte[] bytes, Charset charset) 构造一个新的String由指定用指定的字节的数组解码charset 。  
				代码实现:
					 System.out.println(new String(bytes1,"GBK"));


	3.乱码是怎么产生的?
		编码和解码使用的字符集不一致


四、转换流
	1.为什么会出现这个转换流?
		就是为了解决中文的读和写的乱码问题
			//在IO流中,以Stream结尾的肯定是字节流,以er结尾的肯定是字符流

	2.相关的类
		1.InputStreamReader
			字符输入流
			
		2.OutputStreamWriter 
			字符输出流

	3.构造方法
		//字符输入流
		(1)InputStreamReader​(InputStream in) 创建一个使用默认字符集的InputStreamReader。 
		(2)InputStreamReader​(InputStream in, String charsetName) 创建一个使用命名字符集的InputStreamReader。  
				//字符流 = 字节流 + 编码表

		//字符输出流
		(1)OutputStreamWriter​(OutputStream out) 创建一个使用默认字符编码的OutputStreamWriter   
		(2)OutputStreamWriter​(OutputStream out, String charsetName) 创建一个使用命名字符集的OutputStreamWriter  


	4.字符流写数据的物种方式
		(1)void write(int c) 写一个字符
		(2)void write(char[] cbuf) 写入一个字符数组
		(3)void write(char[] cbuf, int off, int len) 写入字符数组的一部分
		
		(4)void write(String str) 写一个字符串  //特别好用
		(5)void write(String str, int off, int len) 写一个字符串的一部分


	//面试题:close()方法和flush()方法的区别?
		flush:是将数据从内存的缓冲区刷新到本地文件
		close:首先将数据从内存缓冲区刷新到本地文件,接下来还会将资源释放掉

	5.字符流读数据的两种方式
		(1)int read() 一次读一个字符数据
				//返回值  就是读取到的文件的内容
		(2)int read(char[] cbuf) 一次读一个字符数组数据	
				//返回值是读取到的文件内容的大小,   真正的数据存放在char[]中
		代码实现:
			public class Demo3 {
				public static void main(String[] args) throws IOException {
					InputStreamReader isr = new InputStreamReader(new FileInputStream("day09/a.txt"));

					char[] chars = new char[1024];
					int len;
					while ((len = isr.read(chars))!=-1){
						System.out.println(new String(chars, 0, len));
					}
					isr.close();
				}
			}
		
	6.使用字符流复制文件的案例
		public class Demo2 {
			public static void main(String[] args) throws IOException {
				InputStreamReader isr = new InputStreamReader(new FileInputStream("day09/a.txt"));
				OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("day09/b.txt"));

				char[] chars = new char[1024];
				int len;
				while ((len = isr.read(chars))!=-1){
					osw.write(chars,0,len);
					osw.flush();
				}

				osw.close();
				isr.close();
			}
		}


	7.字符流复制文件改进版
		(1)字符输入流
			*FileReader
				构造方法:FileReader​(String fileName) 创建一个新的 FileReader ,给定要读取的文件的名称。
					举例:
						 FileWriter fw = new FileWriter("day09/b.txt");   //执行这行代码,如果b.txt存在就会被清空,如果不存在,则创建该文件

		(2)字符输出流
			*FileWriter
				构造方法:FileWriter​(String fileName) 构造一个给定文件名的FileWriter对象。  

		
		(3)代码实现
			public class Demo4 {
					public static void main(String[] args) throws IOException {
						FileReader fr = new FileReader("day09/a.txt");
						FileWriter fw = new FileWriter("day09/b.txt");

						int len;
						char[] chars = new char[1024];
						while ((len = fr.read(chars))!=-1){
							fw.write(chars,0,len);
							fw.flush();
						}

						fw.close();
						fr.close();
					}
				}

		(4)InputStreamReader和FileReader有什么区别?
			InputStreamReader:是可以指定编码的,想写什么编码都可以  //一般用在源码中
			FileReader:它只能使用平台默认的编码   //开发中常用

	8.字符缓冲流
		(1)对比着字节缓冲流去学
			*字节缓冲流
				BufferedInputStream
				BufferedOutputStream
				
			*字符缓冲流
				BufferedReader 
				BufferedWriter 
				
		(2)构造方法
			*BufferedReader​(Reader in) 创建使用默认大小的输入缓冲区的缓冲字符输入流。  
				//BufferedReader br = new BufferedReader(new FileReader("day09/a.txt"));
			
			*BufferedReader​(Reader in, int sz) 创建使用指定大小的输入缓冲区的缓冲字符输入流。  	
				//BufferedReader br = new BufferedReader(new FileReader("day09/a.txt"),8192);
				
			//注意:字符缓冲流也仅仅是在字符流的基础上加了一个数组缓冲区,真正干活的还是字符流。所以字符缓冲流可以使用字符流的方法	
				
				
		(3)字符缓冲流复制文件案例
				public class Demo5 {
					public static void main(String[] args) throws IOException {
						BufferedReader br = new BufferedReader(new FileReader("day09/a.txt"));
						BufferedWriter bw = new BufferedWriter(new FileWriter("day09/b.txt"));

						int len;
						char[] chars = new char[1024];
						while ((len=br.read(chars))!=-1){
							bw.write(chars,0,len);
							bw.flush();
						}
						bw.close();
						br.close();
					}
				}
									
	9.字符缓冲流的特有功能 //(☆☆☆☆☆)
		(1)字符缓冲输入流的特有功能
			String readLine()读一行文字。 结果包含行的内容的字符串,不包括任何行终止字符如果流的结尾已经到达,则为null
				//返回值:String类型的,存放的是读取到的文件内容       功能:读取一行数据
					//注意事项:读取的内容不包括回车换行符
		
		(2)字符缓冲输出流特有功能
			void newLine() 写一行行分隔符,行分隔符字符串由系统属性定义
				// 功能:换行   
				//注意事项:可以根据不同操作系统换行
		
		(3)使用字符缓冲流的特有功能来复制文件
			代码实现:
				public class Demo6 {
					public static void main(String[] args) throws IOException {
						BufferedReader br = new BufferedReader(new FileReader("day09/a.txt"));
						BufferedWriter bw = new BufferedWriter(new FileWriter("day09/b.txt"));

						String result = null;
						while ((result=br.readLine())!=null){
							bw.write(result);
							bw.newLine();
							bw.flush();
						}
						bw.close();
						br.close();
					}
				}
			
			//注意: 
				(1)下面三行代码一定要连写
					bw.write(result);
					bw.newLine();
					bw.flush();
		
				(2)使用字符缓冲流特有功能复制文件的时候,会产生一个问题:复制后的文件会多一个换行

//IO流的总结
一、字节流
1.字节输入流
*抽象根类:InputStream
具体子类:FileInputStream
*读数据的方法
(1)int read​() 从该输入流读取一个字节的数据

		(2)int read​(byte[] b) 从该输入流读取最多 b.length个字节的数据到一个字节数组。
						
		(3)int read​(byte[] b, int off, int len) 从该输入流读取最多 len个字节的数据到字节数组。
	
	2.字节输出流
		*抽象根类:OutputStream
			具体子类:FileOutputStream
		
		*写数据的方法 
			(1)void write​(int b) 将指定的字节写入此文件输出流。  
			(2)void write​(byte[] b) 将 b.length字节从指定的字节数组写入此文件输出流。   
			(3)void write​(byte[] b, int off, int len) 将 len字节从指定的字节数组开始,从偏移量 off开始写入此文件输出流。
				
	3.字节缓冲流
		*字节缓冲输入流
				BufferedInputStream
		*字节缓冲输出流
				BufferedOutputStream
					//方法就是字节流的方法
		
	4.复制文件的方式
		(1)一次复制一个字节
				
		(2)一次复制一个字节数组

		(3)字节缓冲流一次复制一个字节
			
		(4)字节缓冲流一次复制一个字节数组

二、字符流
	1.字符输入流 
		*抽象根类 Reader
			具体子类: 
				InputStreamReader:输入转换流
				FileReader:字符输入流
		
		*读数据的方法 
			(1)int read() 一次读一个字符数据
			(2)int read(char[] cbuf) 一次读一个字符数组数据	
		
	2.字符输出流
		*抽象根类 Writer 
			具体子类: 
				OutputStreamWriter:输出转换流
				FileWriter:字符输出流
		
		*读数据的方法
			(1)void write(int c) 写一个字符
			(2)void write(char[] cbuf) 写入一个字符数组
			(3)void write(char[] cbuf, int off, int len) 写入字符数组的一部分
			
			(4)void write(String str) 写一个字符串  //特别好用
			(5)void write(String str, int off, int len) 写一个字符串的一部分
		
	3.字符缓冲流 
		(1)字符缓冲输入流:BufferedReader
			*特有方法:
				String readLine()读一行文字。 结果包含行的内容的字符串,不包括任何行终止字符如果流的结尾已经到达,则为null
			
		(2)字符缓冲输出流 BuffederWriter
			*特有方法:
				void newLine() 写一行行分隔符,行分隔符字符串由系统属性定义
		
	4.复制文件的方式 
		(1)普通字符流一次复制一个字符
		(2)普通字符流一次复制一个字符数组
		(3)字符缓冲流一次复制一个字符
		(4)字符缓冲流一次复制一个字符数据
		(5)字符缓冲流特有功能复制文件
		
	//应用:
		*什么时候使用字符流:
			// "读"或者"写"一个带中文的文件
		*什么时候使用字节流:
			//其他情况下一律使用字节流,比如复制文件、查看非中文文件的内容。。。。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值