字符流与字节流,以及缓存流的基本了解,使用

什么是流?
流是个抽象的概念,是对输入输出设备的抽象,输入流可以看作一个输入通道,输出流可以看作一个输出通道。
输入流是相对程序而言的,外部传入数据给程序需要借助输入流。
输出流是相对程序而言的,程序把数据传输到外部需要借助输出流。

什么是字节流?
字节流–传输过程中,传输数据的最基本单位是字节的流。

什么是字符流?
字符流–传输过程中,传输数据的最基本单位是字符的流

字节流
字节流的类通常以stream结尾

常用的字节输入流主要有:
InputStream
FileInputStream
BufferedInputStream

使用:
将一个TXT中的文本信息打印出来:

在这里插入图片描述
代码:

public class FileInputStreamDemo {
    
    

	public static void main(String[] args) {
    
    
		
		 InputStream is =null;  
		  try {
    
    
			    is = new FileInputStream(new File("E:/java文本/a.txt"));  //内存中得有这个文件夹
			  
			    byte[] chars = new byte[1024];  //在 InputStreamDemo中用字节
				int lenth = 0;	                             
				while((lenth = is.read(chars))!=-1){
    
       //把a.txt读到chars里
				String str = new String(chars,0,lenth);   //循环把字节数组变成字符串
				System.out.println(str);
				}
		} catch (FileNotFoundException e) {
    
    
			e.printStackTrace();
		} catch (IOException e) {
    
    
			e.printStackTrace();
		}finally{
    
    
			try {
    
    
				is.close();  //关闭流
			} catch (IOException e) {
    
    
				e.printStackTrace();
			}
		}
	}
}

运行结果:

在这里插入图片描述
常用的字节输出流主要有:
OutputStream
FileOutputStream
BufferedOutputStream

使用:
将字符串打印到TXT中:

public class Demo {
    
    
	
	//往一个文本文件中写一句话“hello world。”
	public static void main(String[] args){
    
    
		OutputStream os = null;
		try {
    
    
			//1.创建流对象(字节流输出)
			File file = new File("E:/java文本/a.txt");  //如果没有这个文件,会自动创建
			os = new FileOutputStream(file,true);  //OutputStream是抽象类,FileOutputStream是子类,参数为File型
			String str = "hello world.";
			//2.调用流对象的方法进行写入操作
			byte[] bytes = str.getBytes();  //将字符串改为字节数组
			os.write(bytes);  //把bytes写到a.txt里参数为字节数组
						
		} catch (FileNotFoundException e) {
    
    
			e.printStackTrace();
		} catch (IOException e) {
    
    
			e.printStackTrace();
		}finally{
    
    			
			try {
    
    
				//3.释放
				os.close();
			} catch (IOException e) {
    
    
				e.printStackTrace();
			}
		}
	}
}

运行结果:
在这里插入图片描述
字符流

常见的字符输入流有:

Reader
InputStreamReader
FileReader
BufferedReader

使用:

public class FileReaderDemo {
    
    

	public static void main(String[] args) {
    
    
	   
		Reader r1 = null;
		try {
    
    
			r1 = new FileReader(new File("E:/java文本/a.txt"));
			char[] chars = new char[1024];  //定义字符数组,字符通常都是1024的倍数
			int length = 0;
			//因为文件内容不知道多大,用一个循环,每读到1024个输出,每读到1024个输出,
			while((length = r1.read(chars))!=-1){
    
     // Length = r1.read(chars):把r1的内容读到chars字节数组中,返回值为int,当中参数为char型,内容不等于-1说明还没有空
			String str = new String(chars,0,length); //把字符数组中的内容转成字符串
			System.out.println(length+"--------"+str);
			}
		} catch (FileNotFoundException e) {
    
      //读文件的前提是,文件必须存在,否则会抛异常
			e.printStackTrace();
		} catch (IOException e) {
    
    
			e.printStackTrace();
		}finally{
    
    
			try {
    
    
				r1.close();
			} catch (IOException e) {
    
    
				e.printStackTrace();
			}
		}
	}
}

运行结果:

在这里插入图片描述
字符输出流

常见的字符输出流有:

Writer
OutputStreamWriter
FileWriter
BufferedWriter

使用:
往一个文件这个追加字符串

public class FileWriteDemo {
    
    

	public static void main(String[] args) {
    
    
	
		Writer fw = null;
		
		try {
    
    
			//true表面文档里之前的东西不会被覆盖,而是写在后面
			fw = new FileWriter(new File("E:/java文本/a.txt"),true);  
			fw.write("zhangsan  lisi");
		} catch (IOException e) {
    
    
			e.printStackTrace();
		}finally{
    
    
			try {
    
    
				fw.close();
			} catch (IOException e) {
    
    
				e.printStackTrace();
			}
		}
	}
}

运行结果:
在这里插入图片描述

字符缓存流
FileReader和FileWriter在读取的时候是读一次或者写一次就请求磁盘,这样使用的时间非常的长,效率比较低,因此引入BufferedReader和BufferedWriter作为读取和写入的缓存区.

1、 BufferedReader一次读取8K的字符流到内存中,当程序读取字符时会先到BufferedReader中读取,若没有的话BufferedReader再从磁盘中读取,一次又是8k

2、BufferedWriter作为写入缓存区,要写入文件的字符流写入BufferedWriter(缓存中),当刷新或关闭BufferedWriter时,才写入磁盘,减少磁盘的写入次数,提高效率

字符缓存输入流:
将TXT中的数据加到程序中:

public class BufferedReaderDemo {
    
    

	public static void main(String[] args) {
    
    
		BufferedReader br = null;
		try {
    
    
			br = new BufferedReader(new FileReader(new File("E:/java文本/a.txt")));
			
			String str = null;
			while((str = br.readLine()) != null){
    
      //readLine()为每次读取一行
				System.out.println(str);
			}
		} catch (FileNotFoundException e) {
    
    
			e.printStackTrace();
		} catch (IOException e) {
    
    
			e.printStackTrace();
		}finally{
    
    
			try {
    
    
				br.close();
			} catch (IOException e) {
    
    
				e.printStackTrace();
			}
		}
	}
}

字符缓存输出流:
将字符串输出到TXT中:

public static void main(String[] args) {
    
    
		
		BufferedWriter bw = null;
		
		try {
    
    
			bw = new BufferedWriter(new FileWriter(new File("E:/java文本/a.txt"),true));  //其实是对流对象进行包装
			bw.newLine(); //写入一行空行
			bw.write("你好,我好,大家好");
		} catch (IOException e) {
    
    
			e.printStackTrace();
		}finally{
    
    
			try {
    
    
				bw.flush(); //将缓存数据刷到硬盘上
				bw.close(); //关闭
			} catch (IOException e) {
    
    
				e.printStackTrace();
			}
		}
	}

实例:将a.txt中的数据拷贝到d.txt中
代码:

public class BufferedInputStreamAndBufferedOutputSream {
    
    

	public static void main(String[] args) {
    
    
		//a.txt拷贝到d.txt
		BufferedInputStream bis = null;
		BufferedOutputStream bos = null;
		try {
    
    
			bis = new BufferedInputStream(new FileInputStream(new File("E:/java文本/a.txt")));  //外内
			bos = new BufferedOutputStream(new FileOutputStream(new File("D:\\d.txt")));  //内外
			byte[] bytes = new byte[1024];
			int length = 0;
			while((length=bis.read(bytes))!=-1){
    
    
				bos.write(bytes, 0, length);
			}
		} catch (FileNotFoundException e) {
    
    
			e.printStackTrace();
		} catch (IOException e) {
    
    
			e.printStackTrace();
		}finally{
    
    
			try {
    
    
				bos.flush();
				bos.close();
				bis.close();
			} catch (IOException e) {
    
    
				e.printStackTrace();
			}
		}
	}
}

对于现在相同的功能发现有两组操作类可以使用,那么在开发中到底该怎么使用哪种会更好呢?

关于字节流和字符流的选择没有明确的定义要求,但是有如下的选择参考:
(1)java最早提供的实际上自由字节流,而在JDK1.1之后才增加了字符流;
(2)字符数据可以方便地进行中文的处理,但是字节数据处理起来会比较麻烦;
(3)在网络传输或者是进行数据保存的时候,数据操作单位都是字节,而不是字符;
(4)字节流和字符流在操作形式上都是类似的,只要一种流会使用了,其他的留都可以采用同样的方式完成。
(5)字节流操作时没有使用到缓冲区,字符流操作时需要缓冲区处理数据,字符流会在关闭的时候默认清空缓冲区,如皋现在操作时没有关闭,则用户可以使用flush()方法手工清空缓冲区。

所以对于字节流和字符流的选择,我们建议:在开发中尽量都去使用字节流进行操作,因为字节流可以处理图片、音乐、文字,也可以方便进行传输或者文字的编码转换;如果在处理中文的使用考虑字符流。

猜你喜欢

转载自blog.csdn.net/weixin_42409759/article/details/107747087