21-I/O(输入输出流)-字符与字节

大家好,我是被白菜拱的猪。

1.输入输出流介绍

在我们现阶段敲的代码中,一般是基于console(控制台)实现。
我们把数据输出是靠System.out —System.out.print(“输出的目标是屏幕”)。
输入则是System.in.它是先定义一个扫描仪对象,对console上用户输入的数据进行扫描
Scanner scan=new Scanner(System.in);输入的来源,来自于Console中用户输入
(1)如何判断输出输出流
输入输出的判断是以程序为参照物
读取一个文件 —输入(程序中)
写入一个文件 —输出(信息从程序中来)
(2)读(read)是输入,写(write)是输出
我们把程序代码想象成我们自己的脑子,我们读一本书,是不是一个知识输入到脑子里面的一个过程。然后我们有了些想法,把自己脑子里面想的东西写在纸上,这是不是一个输出的过程。一切的一切都是以我们的脑子为参照物也就是以程序为参照物。
(3)JDBC,程序与数据库之间的输入输出
在这里插入图片描述
输入流输出流就是两个数据传输通道,就好比我们喝饮料的时候的那根吸管。我们判断输入输出流的方向很简单,就是以我们自己为参照物,像我们和奶茶的时候,是不是狠狠的把管子插进去,戳出一个洞来。在具体的程序当中,我们就是以程序为参照物,把管子插进数据库中,然后我们通过这个管子获取数据,所以输入输出流的方向都是指向数据库。我们喝珍珠奶茶,是不是靠我们嘴巴一吸这个珍珠就上来了,数据也是一样。图中绿色箭头的流向就是数据的流向。
(4)文件与文件的输入输出
我们前面讲的是程序与数据库之间的数据走向。我们想把一个文件里面的数据复制到另一个文件,我们就想这个文件与文件之间是不是也有个管道,没错,之前的那个文件我们叫做源文件,要写进数据的那个文件叫做目标文件。他们之间有个小口,能让数据出去或者进去,源文件那个口插的是输出流管道,目标文件插的是输入流管道。这两个管道名字都不相同,是两个独立的管道。是不能直接相连接的。而是中间借助程序来实现数据的交互。如图所示,输入流输出流的指向是以程序为参照物,想想那个吸管是怎么插进去的。
(5)两种常见的输入输出流
Reader/Writer 里面的数据是以字符的形式传输,主要是文本
InputStream/OutStream里面的数据是以字节的形式传输,主要是超文本(像图片,音频这些)

2.下面我们就讲讲怎么将文件中的数据写入另一个文件中去的

(1)首先我们要先创建两个文件File,一个是源文件,一个是目标文件。

	//源
			File 源文件 = new File("d:/test0807/a.txt");
			
			//目标
			File 目标文件 = new File("d:/test0807/x.txt");

2)创建输入流,输出流(两个管道),并告诉他们是插在哪里的。

			FileReader 输入流 = new FileReader(源文件);
			
			FileWriter 输出流 = new FileWriter(目标文件);

这里的FIleReader就是就是一种输入流,参数就是告诉他插在哪里,也就是连接哪个文件。
(3)创建一个缓存区,先把数据存到程序中,然后在写入目标文件,这里Reader/Wrieter 是以字符形式,所以我们定义一个字符数组先缓存这些数据。那字符数组应该多大的长度呢?像我们现实生活中要把很多沙子从生产地运送到工地,我们不是建造一个能够完全装完的打车而是很多小车多批次的运输。这里缓冲也是这个道理,我们把字符数组想象成一个小车,来来回回的运,直到运完为止,所以这里应该是个循环。
还有一种情况我们需要考虑,假如我们定义字符数组长度为5,源文件长度13,所以要运三次,所以目标文件的长度为15,那是不是有2个字符的空间浪费了,为了避免这种浪费,write()可以帮我们实现

			char[] 临时缓冲区 = new char[5];
			
			int len = 0;
			while ((len = 输入流.read(临时缓冲区)) > 0) {
				输出流.write(临时缓冲区, 0, len);
			}
			

首先定义len=0,用它来等于从源文件读出数据的长度,假如大于0,然后写进目标文件,等于0就说明读完了。 输出流.write(临时缓冲区, 0, len);的意思就是像缓冲区里面的数据接着目标文件的数据后面接着写,0代表偏移量,就比如要将“大家好我是大帅哥”,第一个循环写进去的是“大家好我是”共5个字符,假如偏移量是-1,那么后面的内容就是“大家好我大帅哥”将“是”覆盖掉了,len代表写进去的长度。在解释一遍,输出流.write(临时缓冲区, 0, len);就是将临时缓冲区的数据按照偏移量为0写进len个长度,按照之前讲的13,最后长度为3.所以避免了浪费。
(4)最后输入流输出流打开之后别忘了关闭,饮料不喝了要盖上盖子。

			输入流.close();
			输出流.close();

下面是完整代码

public static void main(String[] args) {
		try {

			//源
			File 源文件 = new File("d:/test0807/a.txt");
			
			//目标
			File 目标文件 = new File("d:/test0807/x.txt");
			
			FileReader 输入流 = new FileReader(源文件);
			
			FileWriter 输出流 = new FileWriter(目标文件);
			
			/*
			 * 输入流:可以读取源文件中的数据到【程序】中
			 * 输出流:可以把【程序】中的数据,写入到目标文件
			 * */
			
			//创建一个临时存储区域,buffer(缓冲)
			char[] 临时缓冲区 = new char[5];
			
			int len = 0;
			while ((len = 输入流.read(临时缓冲区)) > 0) {
				输出流.write(临时缓冲区, 0, len);
			}
			
			输入流.close();
			输出流.close();
			
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

下面是FIleInputStream/FileOutputStream示例
差别就是一个是char数组,一个是byte数组

public static void main(String[] args) {
		try {
			File 源文件 = new File("d:/test0807/normal.png");
			
			File 目标 = new File("d:/test0807/target.png");
			
			InputStream 输入流 = new FileInputStream(源文件);
			
			OutputStream 输出流 = new FileOutputStream(目标);
			
			byte[] buffer = new byte[1024];
			
			int len = 0;
			while ((len = 输入流.read(buffer)) > 0) {
				输出流.write(buffer, 0, len);
			}
			
			/*输入流.read(buffer);
			输出流.write(buffer);*/
			
			输入流.close();
			输出流.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
发布了24 篇原创文章 · 获赞 4 · 访问量 2038

猜你喜欢

转载自blog.csdn.net/weixin_44226263/article/details/98881555