Java——I/O流(一):字节流(概念理解+应用举例)

news/2025/2/26 13:34:23

1.I/O流概述

定义:I/OInput/Output)流,即输入/输出流,是 Java 中实现输入/输出的基础,它可以方便地实现数据的输入/输出操作。

可分为如下几类:👇👇👇 

结构:Java 中的 I/O 流主要定义在 java.io 包中,该包下定义了很多类,其中有4个类为流的顶级类,分别为 InputStream OutputStreamReader Writer 

说明:①InputStream OutPutStream 是字节流,而 Reader Writer 是字符流。

           ②InputStreamReader是输入流,而OutPutStreamWriter是输出流。

           ③下图中4个顶级类都是抽象类,并且是所有流类型的父类。

 

2.字节流概述 

定义:在计算机中,无论是文本、图片、音频还是视频,所有文件都是以二进制(字节)形式存在的,I/O流中针对字节的输入/输出提供了一系列的流,统称为字节流 

说明:①字节流是程序中最常用的流。

           ②JDK,所有的字节输入流都继承自 InputStream,所有的字节输出流都继承自 OutputStream

2.1 字节输入流InputStream常用的方法 

2.2 字节输出流OutputStream常用的方法 

2.3 InputStream和OutputStream的继承体系 

 

3.字节流读写文件 

说明:①针对文件的读写操作,JDK专门提供了两个类,分别是 FileInputStream FileOutputStream

           ②FileInputStream InputStream 的子类,它是操作文件的字节输入流,专门用于读取文件中的数据 

           ③文件读取数据是重复的操作,因此需要通过循环语句来实现数据的持续读

3.1 字节输出流读写文件 

写入数据的原理(内存-->硬盘):

Java程序 → Java虚拟机 → 操作系统 → 操作系统调用写数据的方法 → 把数据写到文件中

写数据的时候,会把要写入的数据转换为二进制数。在打开文件的时候,都会查询编码表(例如:ASCII表),把字节转换为字符表示。

import java.io.*;
public class IODemo01 {
	public static void main(String[] args) throws IOException {
		//使用文件名创建字节流对象
		FileOutputStream fos1=new FileOutputStream("FOS1.txt");
		fos1.write(65);//依次写出三个字节的数据
		fos1.write(66);
		fos1.write(67);
		fos1.close();//关闭字节输出流,并释放资源
		
		FileOutputStream fos2=new FileOutputStream("FOS2.txt");
		byte[] bytes2={97,98,99};//创建一个byte数组
		fos2.write(bytes2);//将bytes2字节数组中的所有字节写入fos2输出流
		fos2.close();//关闭字节输出流,并释放资源
		
		FileOutputStream fos3=new FileOutputStream("FOS3.txt");
		byte[] bytes3={97,98,99,100,101,102};
		//将bytes3数组中从1开始往后的4个字节写入fos3输出流
		fos3.write(bytes3,1,4);//即字节98,99,100,101
		fos3.close();//关闭字节输出流,并释放资源
		
		FileOutputStream fos4=new FileOutputStream("FOS4.txt");
		String str1="大佬,你好!";//创建一个字符串
		byte[] bytes4=str1.getBytes();//调用String类的getBytes()方法将该字符串转为byte数组
		fos4.write(bytes4);//将bytes4字节数组中的所有字节写入fos4输出流
		fos4.close();//关闭字节输出流,并释放资源
		
		/**字节输出流的续写,有如下两个构造方法
		 * public FileOutputStream(File file, boolean append)
		 * 创建文件输出流以写入,由指定的File对象表示的文件
		 * 
		 * public FileOutputStream(String name, boolean append)
		 * 创建文件输出流以指定的名称写入文件
		 * 参数中有一个boolean类型的值:true表示追加数据,false表示清空原有数据 
		 */
		FileOutputStream fos5=new FileOutputStream("FOS5.txt",true);
		String str2="一路相遇,";
		byte[] bytes5=str2.getBytes();
		fos5.write(bytes5);//第一次向"FOS5.txt"文件中写入相应的内容
		String str3="感谢有你!";
		byte[] bytes6=str3.getBytes();
		fos5.write(bytes6);//第二次向"FOS5.txt"文件中追加写入相应的内容
		fos5.close();//关闭字节输出流,并释放资源
		
		FileOutputStream fos6=new FileOutputStream("FOS6.txt",true);
		String str4="天行健,君子以自强不息!";
		byte[] bytes7=str4.getBytes();
		fos6.write(bytes7);//第一次向"FOS6.txt"文件中写入相应内容
		String str5="\n";
		byte[] bytes8=str5.getBytes();
		fos6.write(bytes8);//第二次向"FOS5.txt"文件中写入一个换行
		String str6="地势坤,君子以厚德载物!";
		byte[] bytes9=str6.getBytes();
		fos6.write(bytes9);//第三次向"FOS5.txt"文件中写入相应内容
		fos6.close();//关闭字节输出流,并释放资源
	}
}

在运行上述代码之后,我们就可以在指定的文件路径下,找到我们所写的文件以及相应的内容。如下图:👇👇👇 

3.2 字节输入流读写文件

读取数据的原理(硬盘-->内存):
Java程序 → Java虚拟机 → 操作系统 → 操作系统调用读取数据的方法 → 读取文件 

构造方法:
//通过打开与实际文件的连接来创建一个FileInputStream,该文件由文件系统中的路径名name命名
public FileInputStream(String name) throws FileNotFoundException

//通过打开与实际文件的连接来创建一个FileInputStream,该文件由文件系统中的File对象file命名
public FileInputStream(File file) throws FileNotFoundException
import java.io.*;
public class IODemo02 {
	public static void main(String[] args) throws IOException {
		//创建FileInputStream对象,构造方法中绑定要读取的数据源
		FileInputStream fis1=new FileInputStream("E:/Eclipse/Java Project/Love/FOS1.txt");
		System.out.println("读取文件FOS1中的内容:");
		int len=0;
		//read()方法是一个字节一个字节的进行读取
		while((len=fis1.read())!=-1) {
			System.out.print((char)len + " ");
		}
		/*int byte0=fis1.read();
		char ch0=(char)byte0;//65 对应字符 A
		System.out.println(byte0 + " 对应:" + ch0);
		int byte1=fis1.read();
		char ch1=(char)byte1;//66 对应字符 B
		System.out.println(byte1 + " 对应:" + ch1);
		int byte2=fis1.read();
		char ch2=(char)byte2;//67 对应字符 C
		System.out.println(byte2 + " 对应:" + ch2);
		int byte3=fis1.read();
		char ch3=(char)byte3;
		System.out.println(byte3 + " 对应:" + ch3);
		此时已将FOS1文件中的内容全部读完,再进行读取,将输出-1*/
		fis1.close();//关闭字节输入流,并释放资源
                System.out.print();
		
		FileInputStream fis2=new FileInputStream("E:/Eclipse/Java Project/Love/FOS2.txt");
		System.out.println("读取文件FOS2中的内容:");
		byte[] bytes1=new byte[3];
		int len1=fis2.read(bytes1);
		for(int i=0;i<len1;i++) {
			char ch3=(char)bytes1[i];
			System.out.print(ch3 + " ");
		}
		fis2.close();//关闭字节输入流,并释放资源
		System.out.println();
		
		FileInputStream fis3=new FileInputStream("E:/Eclipse/Java Project/Love/FOS3.txt");
		System.out.println("读取文件FOS3中的内容:");
		byte[] bytes2=new byte[5];
		int len2=fis3.read(bytes2,1,4);//len2=4
		for(int i=1;i<=4;i++) {
			char ch4=(char)bytes2[i];
			System.out.print(ch4 + " ");
		}
		fis3.close();//关闭字节输入流,并释放资源
		System.out.println();
	}
}

在运行上述代码之后,可以看到下面的运行结果,以及我们拷贝文件的结果。如下图:👇👇👇

3.3 字节缓冲流的效率测试

缓冲流,也叫高效流。能够高效读写缓冲流,能够转换编码的转换流,能够持久化存储对象的序列化对象等等。它是四个基本File流的增强,所以也是4个流,按照数据类型分类。

  • 字节缓冲流:BufferedInputStream,BufferedOutputStream
  • 字符缓冲流:BufferedReader,BufferedWriter

缓冲流的基本原理,是在创建流对象时,会创建一个内置的默认大小的缓冲区数组,通过缓冲区读写,减少系统IO读取次数,从而提高读写的效率。

说明:除了定义字节缓冲区来提高文件拷贝效率外,IO中还提供了两个字节缓冲流来提高文件拷贝效率:BufferedInputStream 和 BufferedOutputStream它们的构造方法中分别接收 InputStream OutputStream 类型的参数作为对象,在读写数据时提供缓冲功能。 

构造方法:
//创建一个新的字节缓冲输入流
BufferedInputStream(InputStream in)
BufferedInputStream(InputStream in, int size)

//创建一个新的字节缓冲输出流
BufferedOutputStream(OutputStream out)//将数据写入指定的底层输出流
BufferedOutputStream(OutputStream out, int size)//将具有指定缓冲区大小的数据写入指定的底层输出流

//参数:
InputStream in:字节输入流
OutputStream out:字节输出流
int size:缓冲区大小,不写的话,默认
import java.io.*;
public class IODemo03 {
	public static void main(String[] args) throws IOException {
		//普通的文件拷贝
		long beginTime1=System.currentTimeMillis();
		FileInputStream FIS1=new FileInputStream("E:/Eclipse/Java Project/Love/集合.jpg");
		FileOutputStream FOS1=new FileOutputStream("E:/Eclipse/Java Project/Love/集合1.jpg");
		System.out.print("普通的文件拷贝");
		int length1=0;
		while((length1=FIS1.read())!=-1) {
			FOS1.write(length1);
		}
		FIS1.close();//关闭字节输入流,并释放资源
		FOS1.close();//关闭字节输出流,并释放资源
		long endTime1=System.currentTimeMillis();
		System.out.println("花费的时间为:" + (endTime1-beginTime1) + "ms");
				
		//使用字节流的缓冲区进行文件拷贝
		long beginTime2=System.currentTimeMillis();
		FileInputStream FIS2=new FileInputStream("E:/Eclipse/Java Project/Love/集合.jpg");
		FileOutputStream FOS2=new FileOutputStream("E:/Eclipse/Java Project/Love/集合2.jpg");
		System.out.print("使用字节流的缓冲区进行文件拷贝");
		int length2=0;
		byte[] bytes1=new byte[1024];
		while((length2=FIS2.read(bytes1))!=-1) {
			FOS2.write(bytes1,0,length2);
		}
		FIS2.close();//关闭字节输入流,并释放资源
		FOS2.close();//关闭字节输出流,并释放资源
		long endTime2=System.currentTimeMillis();
		System.out.println("花费的时间为:" + (endTime2-beginTime2) + "ms");
		
		//使用字节缓冲流进行文件拷贝
		long beginTime3=System.currentTimeMillis();
		BufferedInputStream BIS=new BufferedInputStream(new FileInputStream("E:/Eclipse/Java Project/Love/集合.jpg"));
		BufferedOutputStream BOS=new BufferedOutputStream(new FileOutputStream("E:/Eclipse/Java Project/Love/集合3.jpg"));
		System.out.print("使用字节缓冲流进行文件拷贝");
		int length3=0;
		byte[] bytes2=new byte[1024];
		
		while((length3=BIS.read(bytes2))!=-1) {
			BOS.write(bytes2,0,length3);
		}
		BIS.close();//关闭字节缓冲输入流,并释放资源
		BOS.close();//关闭字节缓冲输出流,并释放资源
		long endTime3=System.currentTimeMillis();
		System.out.println("花费的时间为:" + (endTime3-beginTime3) + "ms");
	}
}

从图中以看出拷贝文件所消耗的时间明显减少了很多,这说明使字节缓冲流同样以有效的提高程序的传输效率

这种方式与字节流的缓冲区类似,都对数据进行了缓冲,从而有效的提高了数据的读写效率 


http://www.niftyadmin.cn/n/712631.html

相关文章

UVa 10340:All in All(字符串)

题目传送门&#xff1a;https://cn.vjudge.net/problem/UVA-10340 简单的字符串题目 AC code&#xff1a; #include <iostream> #include <string> using namespace std;int main() {string s, t;while (cin >> s >> t) {unsigned int i 0, j 0;w…

python绘图苹果_啥是佩奇,Python 告诉你!

今天&#xff0c;被《啥是佩奇》这支广告片刷屏了。佩奇明明是个喜剧角色&#xff0c;却看哭了所有人。《啥是佩奇》&#xff1f;&#xff1f;&#xff1f;快过年了&#xff0c;在农村爷爷给城里的小孙子打电话&#xff0c;小孙子说想要“佩奇”&#xff0c;为了满足小孙子的愿…

Java——I/O流(二):字符流(概念理解+应用举例)

1.开篇 承接博主上一篇博文的字节流&#xff0c;在这篇博文中&#xff0c;我主要为大家介绍一下I/O流中的字符流&#xff0c;有关字节流的内容可以参考下面博文的链接&#xff1a;&#x1f447;&#x1f447;&#x1f447; https://blog.csdn.net/weixin_43823808/article/det…

tbox使用sm2算法_【学术论文】基于非对称算法的工控核心区内嵌认证技术

导读&#xff1a;近年来&#xff0c;工业互联网成为世界范围内的关注热点。作为数字浪潮下工业体系和互联网体系深度融合的产物&#xff0c;工业互联网被视为新一轮工业革命的关键支撑。工业互联网的建设和发展&#xff0c;是新一轮科技革命和产业变革的重大历史机遇&#xff0…

一阶广义差分模型_股票价格数学模型

股票价格数学模型是针对股票价格与时间之间的数量依存关系&#xff0c;通过抽象和简化&#xff0c;采用数学语言和方法&#xff0c;概括地或近似地表述出的一种数学结构。股票价格数学模型从数量关系上对股票价格运动作形式化的描述和刻画&#xff0c;可为研究股票价格运动现象…

Uva 1587:Box

题目传送门&#xff1a;https://cn.vjudge.net/problem/UVA-1587 #include <stdio.h>struct p {int w, h; }ps[6], cps[3];bool isSame(int i, int j) {return (ps[i].w ps[j].w && ps[i].h ps[j].h)|| (ps[i].w ps[j].h && ps[i].h ps[j].w); }boo…

洛谷P1746-离开中山路(BFS)

题目背景&#xff1a; 《爱与愁的故事第三弹shopping》最终章。 题目描述&#xff1a; 爱与愁大神买完东西后&#xff0c;打算坐车离开中山路。现在爱与愁大神在x1,y1处&#xff0c;车站在x2,y2处。现在给出一个nn&#xff08;n<1000&#xff09;的地图&#xff0c;0表示马路…

解决Ubuntu无法从外部应用启动Chrome打开链接的问题

遇到的问题&#xff1a;从外部应用&#xff08;如WPS Presentation&#xff09;打开连接后&#xff0c;chrome只显示一个空的标签&#xff0c;不会自动跳转 平台&#xff1a;Ubuntu 16.04 Desktop 解决办法&#xff1a;https://askubuntu.com/questions/689449/external-links…