Java-基础-IO流

本文详细介绍了Java中的IO流,包括基本概念、分类,如输入流和输出流,以及字节流和字符流的差异。通过类图展示了InputStream、OutputStream作为字节流基类,以及Reader、Writer作为字符流基类的层级结构。文中还强调了处理流的重要性,如缓冲流、转换流和数据流,以及在实际开发中使用IO流的注意事项。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1 基本概念

  • Java把不同类型的输入、输出源抽象为流(stream),其中输入或输出的数据称为数据流(Data Stream),用统一的接口来表示。
  • Java中的io是实现输入和输出的基础,可以方便的实现数据的输入和输出操作。
  • Java把所有的流类型代码都放在java io包下,用于实现输入和输出功能。

2 分类

2.1输入流和输出流

按照流的流向划分,可以分为输入流和输出流。
注意,流向是以内存(程序)的角度来划分的,输入到内存(程序)的就是输入流,从内存(程序)输出的就是输出流,如下图:
在这里插入图片描述

2.1.1输入流

Java的输入流主要是InputStream和Reader作为基类。它们都是一些抽象基类,无法直接创建实例。
对于输入流来说,它们把输入设备抽象为一个“水管”,这个水管的每个“水滴”依次排列。如下图:
在这里插入图片描述
操作位置由隐式的记录指针决定,取出数据后记录指针会自动移动,同时也提供了方法操作记录指针。
字节流和字符流的处理方式是一样的,只是他们的输入/输出单位不同而已,字节流的单位是字节,字符流的单位是字符。

2.1.2输出流

Java的输出流主要是OutputStream和Writer作为基类。它们都是一些抽象基类,无法直接创建实例。
对于输出流来说,它们同样把输出设备抽象为一个“水管”,只是这个水管中没有“水滴”。如下图:
在这里插入图片描述
操作位置由隐式的记录指针决定,输出的“水滴”放置后,记录指针自动移动,同时也提供了方法操作记录指针。
字节流和字符流的处理方式是一样的,只是他们的输入/输出单位不同而已,字节流的单位是字节,字符流的单位是字符。

2.2字节流和字符流

按照操作单元划分,可以分为字节流和字符流。
字节流主要是由InputStream和OutputStream作为基类,而字符流主要是Reader和Writer作为基类。
字节流和字符流的区别:

  • 读写单位不同:字节流以字节(8bit)为单位,字符流以字符为单位,根据码表映射字符,一次可能度多个字节。
  • 处理对象不同:字节流能处理所有类型的数据(如图片、avi等),而字符流只能处理字符类型的数据。
  • 二进制位数:字节流一次操作的是8位二进制,而字符流一次操作的是16位二进制。
  • 中文处理:字节流以字节为单位,故无法处理中文(因一个中文占两个字节)。但字符流可以处理。
  • 缓冲区:字节流是直接对文件进行处理,而字符流存在缓冲区,所有操作在缓冲区完成后再对文件进行处理。

3.类图

在这里插入图片描述

3.1基类

红色底线,是所有输入/输出流的父类,是一个抽象类。
InputStream/Reader:所有的输入流的基类,前者是字节输入流,后者是字符输入流。
OutputStream/Writer:所有的输出流的基类,前者是字节输出流,后者是字符输出流。

3.2节点流

橙色底线,直接与数据源相连,读入或读出。
直接使用节点流,读写不方便,为了更快的读写文件,才有了处理流。
在这里插入图片描述
常用的节点流:

  • 文件处理:FileInputStream、FileOutputStream、FileReader、FileWriter。
  • 数组处理:ByteArrayInputStream、ByteArrayOutputStream、CharArrayReader、CharArrayWriter。
  • 字符串处理:StringReader、StringWriter。
  • 多线程管道通信:PipedInputStream、PipedOutputStream、PipedReader、PipedWriter。

注意,FilterInputStream和FilterOutputStream使用的是设计模式中的装饰器模式。

3.3处理流

处理流和节点流一块使用,在节点流的基础上,再套接一层,套接在节点流上的就是处理流。处理流的构造方法总是要带一个其他的流对象做参数。一个流对象经过其他流的多次包装,称为流的链接。
处理流可细分为:
1、缓冲流,绿色底线,增加缓冲功能,避免频繁读写硬盘。常用的有BufferedInputStream、BufferedOutputStream、BufferedReader、BufferedWriter。
2、转换流,紫色底线,实现字节流和字符流之间的转换。常用的有InputStreamReader、OutputStreamReader。
3、数据流,黑色底线,提供将基础数据类型写入或读取到文件中。常用的有DataInputStream、DataOutputStream。
在这里插入图片描述

4.示例

字节流FileInputStream和缓冲流BufferedInputStream读取文件内容代码:

/**
 * 文件内容打印方法
 * @param filePath  文件路径
 * @return          文件内容
 */
public String filePrint(String filePath){
	File targetFile = new File(filePath);
	BufferedInputStream bufFis = null;                  //缓冲流对象
	StringBuilder stringBuilder = new StringBuilder();  //结果集
	try {
         //基于节点流对象创建缓冲流对象
		bufFis = new BufferedInputStream(new FileInputStream(targetFile));      
		int size = bufFis.available();  //返回输入流中可以被读的bytes字节的估计值
		byte[] buf = new byte[size];    //创建一个缓存字节的容器数组
		int hasRead = 0;                //定义一个变量,保存实际读取的字节数
		while((hasRead = bufFis.read(buf)) != -1){      //循环读取数据
			String fileStr = new String(buf,0,hasRead); //转换数据为String
			stringBuilder.append(fileStr);
		}
	} catch (FileNotFoundException e) {
		e.printStackTrace();
	} catch (IOException e) {
		e.printStackTrace();
	} finally{
		if(bufFis != null){
			try {
				bufFis.close();         //关闭流
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	return stringBuilder.toString();    //返回结果集
}

字节流FileOutputStream和缓冲流BufferedOutputStream写入文件内容代码:

/**
 * 向文件写入指定内容
 * @param filePath  文件路径
 * @param fileMsg   指定内容
 */
public void fileWrite(String filePath,String fileMsg){
	BufferedOutputStream buffFos = null;        //缓冲流对象
	try {
        //基于节点流对象创建缓冲流对象
		buffFos = new BufferedOutputStream(
new FileOutputStream(new File(filePath),true));  
		byte[] data = fileMsg.getBytes();       //把数据源转换为字节数组类型
		buffFos.write(data,0,data.length);      //通过流向文件写入数据
		buffFos.flush();    //刷新流
		System.out.println("文件写入成功!!");
	} catch (FileNotFoundException e) {
		e.printStackTrace();
	} catch (IOException e) {
		e.printStackTrace();
	}finally{
		if(buffFos != null){
			try {
				buffFos.close();        //关闭流
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}

5.注意事项

在实际的项目中,所有的IO操作都应该放到子线程中操作,避免堵住主线程。

6.参考文献

Java IO流学习总结一:输入输出流

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值