java中IO流基础

本文详细介绍了Java中IO流的基础知识,包括文件操作、IO流的概念、作用场景、设备分类以及IO流的四大父类。重点讲述了File类的使用,如路径的绝对与相对路径,以及File类的常用方法。此外,还详细讲解了字节流InputStream和OutputStream,以及字符流Reader和Writer的基本用法,并通过文件复制案例展示了如何实际操作IO流进行文件读写。

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

文件操作

​ 顾名思义, 操作磁盘上的某⼀个⽂件或者某⼀个⽂件夹。 可以对他们进⾏创建、 删除、 移动、 属性获取、 属性设置等操作。 但是, 并不包含读取⽂件的内容、 拷⻉⽂件。

​ 在Java中, 使⽤ java.io.File 类描述⼀个⽂件, 或者是⼀个⽂件夹。

IO流

什么是IO流

IO流: Input/Output Stream
流: 指的是⼀串流动的数据, 在数据在流中按照指定的⽅向进⾏流动。 实现数据的读取、写⼊的功能。
**作⽤:**实现两个设备之间数据的传递

IO流的使⽤场景

使⽤File类, 只能做关于⽂件的操作, 获取属性、 创建⽂件、 删除⽂件、 移动⽂件等操作, 但是不包含读取⽂件中的内容。 如果需要读取、修改⽂件中的内容, 此时就需要使用IO流来完成了。

使⽤场景: 对某⼀个⽂件进⾏读取或者写⼊操作。

注意事项:

​ IO流是对⼀个⽂件进⾏读写的, 不是⼀个⽂件夹! 在使⽤IO流的时候, 不要建⽴与⼀个⽂件夹的连接。

设备

设备概念:能输出或者输⼊数据的都可以成为设备

设备:磁盘(硬盘),内存,键盘,⽂件,⽹络,控制台

⽹络:当前主机之外的⽹上资源

IO流的分类

按照不同的分类标准, 能够得到不同分类的IO流:
按照传输数据的单位:
字节流: 传输的是字节,是以字节为单位的。可以操作任意类型的数据 ------⾳频,视频,⽂件,图⽚等
字符流: 传输的是字节,不同点是在传输过程中加⼊了编码的操作,让我们的操作更⽅便------⽂本

​ 按照数据传输的⽅向:
​ 以内存为参考
​ 输⼊流: 数据从其他设备传到内存
​ 输出流: 数据从内存传到其他设备

基础的IO流类的简介

其实在 java.io 包中, 有很多很多的类, 都是来描述IO流的。 但是基本上所有的IO流的类, 都是直接或间接的继承⾃四⼤⽗类流。

字节流的两个⽗类:

​ 字节输⼊流:InputStream

​ 字节输出流:OutputStream

字符流的两个⽗类:

​ 字符读⼊流:Reader

​ 字符写出流:Writer

IO流使⽤的注意事项

​ 四⼤⽗类流, 都是抽象类, 都不能实例化对象。 因此, 需要借助他们的⼦类实现数据的读写。
​ 流对象⼀旦实例化完成, 将建⽴⼀个程序与⽂件之间的连接。 这个连接会持有
这个⽂件。 如果这个连接不断, 此时这个⽂件就是⼀个被使⽤中的状态, 此时将⽆法对这个⽂件进⾏其他的操作, 例如删除。
​ ⼀个流在使⽤完成之后, 切记! ⼀定要进⾏流的关闭。

⽂件操作

绝对路径和相对路径

相关概念

路径: ⽤来描述⼀个⽂件所在的地址, ⽤来定位⼀个⽂件的。 可以分为绝对路径和相对路径。

绝对路径: 从磁盘的根⽬录开始, ⼀层层的向下查找, 直到找到这个⽂件。

相对路径: 找到⼀个参照物, 相对于这个参照物的路径。

对比

在这里插入图片描述

分隔符

分隔符的简介

在描述路径的字符串中, 有两种分隔符, 是⽐较常⻅的: ⽬录分隔符 和 路径分隔符。

⽬录分隔符

分隔开⼀个路径中的不同的⽂件夹, ⽤来描述层级关系、 包含关系。

在不同的操作系统中, ⽬录分隔符是不⼀样的。 在windows中, 使⽤ \ 作为⽬录分隔符; 在⾮windows的操作系统中, 例如: Linux、Unix… 使⽤的是 / 作为⽬录分隔符。

路径分隔符
分隔开⼀个字符串中的多个路径的。
在不同的操作系统中, 路径分隔符是不⼀样的。 在windows中, 使⽤ ; 作为路径分隔符; 在⾮windows的操作系统中, 例如: Linux、Unix… 使⽤的是 : 作为路径分隔符。

分隔符的表示

如果你的程序只需要考虑部署在windows平台, 那么只需要按照windows的规范书写就可以; 如果你的程序只需要部署到linux上, 那么只需要按照linux的规范书写就可以。 但是, 如果你的程序需要考虑在不同的平台上部署运⾏, 此时就需要使⽤以下⽅法进⾏分隔符的获取。

在这里插入图片描述

File类

File类的简介

File是 java.io 包中的⼀个类。 是对磁盘上的某⼀个⽂件、⽂件夹(⽬录)的描述。所谓的⽂件操作, 其实都是需要使⽤这个类来完成的。

File类的构造方法

在这里插入图片描述

File类的常⽤⽅法

  1. ⽂件属性获取⽅法

在这里插入图片描述

  1. ⽂件操作⽅法

在这里插入图片描述

3)子文件获取

在这里插入图片描述

基础的IO流

建⽴程序与⽂件的连接

其实, 就是建⽴了程序与⽂件之间连接的管道, 实现数据在这个管道之内进⾏流动。 管道分为不同的类型: 字节输⼊流、 字节输出流、 字符输⼊流、 字符输出流。 下⾯以字节输⼊InputStream 为例。

标准流程

​ try结构外⾯, 声明流对象, 为了在finally中使⽤。

​ 在try结构⾥⾯, 实例化流对象, 并捕获异常。

​ 在finally结构中, 对流进⾏关闭。 在关闭的时候, 需要考虑流对象是否是null, 以及要处理 IOException 异常。

try结构的特殊使⽤

在 JDK1.7 之后, 可以在try后⾯添加⼀对⼩括号。 将AutoClosable 接⼝实现类的对象, 实例化放到⼩括号中完成。 此时, 在try结构执⾏结束的时候, 会⾃动的调⽤AutoClosable接⼝实现类中的close⽅法, 进⾏流的关闭。 这样写的流的建⽴⽐较简
单, 也是后⾯我们最主要使⽤的⽅式。

try (InputStream inputStream = new
FileInputStream("file\\day25\\source")) {
	// 数据的读取操作
	} catch (FileNotFoundException e) {
		e.printStackTrace();
	} catch (IOException e) {
		e.printStackTrace();
	}
	System.out.println(new
		File("file\\day25\\source").delete());
}

InputStream

InputStream简介

这是⼀个字节输⼊流。 从⽅向来说, 是⼀个输⼊流, 数据是从⽂件中流动到程序中(数据从其他设备到内存), 是为了读取⽂件中的数据的。 从数据单位来说, 这个流中流动的数据直接是字节的形式。

⽂件的读取

注意:
1.为了⽅便测试,我们可以先通过字节输出流或者⼿动在当前⼯程中创建⼀个test1.txt⽂件,写⼊字符串abcde
2.有三种读取数据的⽅式第⼀:⼀次读取⼀个字节;第⼆:⼀次读取多个字节;第三:⼀次读取全部字节
三种读取数据的⽅式中,推荐使⽤第⼆种,⼀次读取多个字节

  1. ⼀次读取⼀个字节
    read():⼀个字节⼀个字节的读,每次读出⼀个字节
while ((num = inputStream.read()) != -1) {
	System.out.print((char)num);
}

在这里插入图片描述

  1. ⼀次读取多个字节
    read(数组):⼀次可以读出多个字节,数组的作⽤:每次会将读出的字节临时放到这个数组中
while ((num = inputStream.read(arr)) != -1){
	System.out.println(new String(arr,0,num)+"
num:"+num);
}

在这里插入图片描述

  1. ⼀次读取全部字节
    可以通过available()⽅法获取全部字节个数
// 1. 建⽴程序与⽂件之间的连接,⽤来读取这个⽂件
try (InputStream inputStream = new
	FileInputStream("test1.txt")) {
	// 2. 读取字节流中的数据,需要有⼀个字节数组,⽤来读取数据
	//获取⽂件的字节个数
	//注意:这种⽅式适合⽂件的字节数⽐较⼩的时候,⼤概是⼏kb之内.
	int num = inputStream.available();
	//2.读
	byte[] bytes = new byte[num];
	inputStream.read(bytes);
	System.out.println(new String(bytes));
} catch (IOException e) {
	e.printStackTrace();
}

OutputStream

OutputStream简介

字节输出流。 从⽅向上来分, 是⼀个输出流, 数据从程序中流动到⽂件中(数据从内存到其他设备), 实现⽂件的写操作。 从流中流动的数据单位来分, 是⼀个字节流,流中流动的数据直接是字节的形式。

⽂件的写

try (OutputStream outputStream = new
FileOutputStream("test1.txt",true)) {
	// 2. 准备需要写⼊到这个⽂件中的数据
	String message = "你好,师姐";
	// 3. 将数据写⼊到输出流中,由输出流写⼊到⽂件中
	//将字符串转成字节数组
	outputStream.write(message.getBytes());
	// 冲刷缓冲区,将缓冲区中的数据强制流动到⽂件中。
	// 在流关闭的时候,会⾃动的调⽤。
	//注意:当我们进⾏循环写⼊操作时,最好通过flush()⽅法刷新
	outputStream.flush();
} catch (IOException e) {
	e.printStackTrace();
}

案例: ⽂件拷⻉

需求分析

实现, 将⼀个⽂件拷⻉到另外⼀个地⽅。 注意, 这个不是剪切, 拷⻉完成之后,原⽂件还在。
实现⽅式: 借助两个流来完成。
使⽤字节输⼊流输⼊, 循环读取原⽂件中的数据。
使⽤字节输出流, 将每次读取到的数据, 写⼊到⽬标⽂件中。
图示:

在这里插入图片描述

Reader

Reader的简介

这是⼀个字符输⼊流。 从⽅向来说, 是⼀个输⼊流, 数据是从⽂件中流动到程序中(数据从其他设备到内存), 是为了读取⽂件中的数据的。 从数据单位来说, 这个流中流动的数据以字节为单位的,不同的是在传输过程中加⼊了编码的操作,让我们的操作更⽅便。

try (Reader reader = new FileReader("file\\day25\\src"))
        {
        // 1. 实例化⼀个字符数组
            char[] array = new char[100];
        // 2. 声明⼀个变量,⽤来记录每次读取到了多少个数据
            int length = 0;
            // 3. 循环读取数据
            while ((length = reader.read(array)) != -1) {
                String str = new String(array, 0, length);
                System.out.print(str);
            }
        }
        catch (IOException e) {
            e.printStackTrace();
        }

Writer

Writer的简介

字符输出流。 从⽅向上来分, 是⼀个输出流, 数据从程序中流动到⽂件中(数据从内存到其他设备), 实现⽂件的写操作。 从流中流动的数据单位来分, 是⼀个字符流,流中流动的数据是以字节为单位,不同的是在传输过程中加⼊了编码的操作,让我们的操作更⽅便。

⽂件的写操作

try (Writer writer = new
FileWriter("file\\day25\\target", true)) {
	// 2. 将数据写⼊到输出流中
		writer.write("hello, world");
// 3. 冲刷缓冲区
	writer.flush();
}
catch (IOException e) {
	e.printStackTrace();
}

案例: ⽂件拷⻉

需求分析

实现, 将⼀个⽂件拷⻉到另外⼀个地⽅。 注意, 这个不是剪切, 拷⻉完成之后,原⽂件还在。
实现⽅式: 借助两个流来完成。
使⽤字符输⼊流, 循环读取原⽂件中的数据。
使⽤字符输出流, 将每次读取到的数据, 写⼊到⽬标⽂件中。

示例代码

private static void fileCopy2(String srcPath, String dstPath) {
	// 2. 循环读取⽬标⽂件中的数据
	try (Reader reader = new FileReader(srcPath); Writer writer= new FileWriter(dstPath)) {
		// 3. 循环读取源⽂件中的数据
		char[] array = new char[100];
		int length = 0;
		while ((length = reader.read(array)) != -1) 		{
			// 4. 将读取到的数据写⼊到输出流
			writer.write(array, 0, length);
		}
		writer.flush();
		return true;
	}
	catch (IOException e) {
		e.printStackTrace();
		return false;
	}
}

FileWriter(dstPath)) {
// 3. 循环读取源⽂件中的数据
char[] array = new char[100];
int length = 0;
while ((length = reader.read(array)) != -1) {
// 4. 将读取到的数据写⼊到输出流
writer.write(array, 0, length);
}
writer.flush();
return true;
}
catch (IOException e) {
e.printStackTrace();
return false;
}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值