File类与IO流 2
File类与IO流 2
2.2流的分类
java.io包下提供了各种“流"类和接口,用以获取不同种类的数据,并通过标准的方法输入或输出数据。·
- 按数据的流向不同分为:输入流和输出流。
- 输入流︰把数据从其他设备上读取到内存中的流。
-以InputStream、Reader结尾 - 输出流:把数据从内存中写出到其他设备上的流。
-以outputStream、Writer结尾
- 输入流︰把数据从其他设备上读取到内存中的流。
- 按操作数据单位的不同分为:字节流(8bit)和字符流(16bit) 。
- 字节流︰以字节为单位,读写数据的流。
以InputStream、OutputStream结尾。 - 字符流∶以字符为单位,读写数据的流。
-以Reader、Writer结尾
- 字节流︰以字节为单位,读写数据的流。
- 根据lo流的角色不同分为:节点流和处理流。
- 节点流:直接从数据源或目的地读写数据
- 处理流:不直接连接到数据源或目的地,而是“连接”在已存在的流(节点流或处理流)之上,通过对数据的处理为程序提供更为强大的读写功能。
2.3流的API
.Java的Io流共涉及40多个类,实际上非常规则,都是从如下4个抽象基类派生的。
(抽象基类) | 输入流 | 输出流 |
---|---|---|
字节流 | InputStream | OutputStream |
字符流 | Reader | Writer |
字节与字符的区别
字节和字符的区别是一个常见的计算机基础知识问题,它涉及到数据的存储和编码方式。简单地说,字节是计算机存储数据的最小单位,它由8位二进制数字组成,可以表示0到255之间的任意数值。字符是计算机中使用的字母、数字、符号等,它们可以用不同的编码方式来表示,例如ASCII码、UTF-8码、Unicode码等。不同的编码方式对应不同的字符集,也就是可以表示的字符范围。一个字符可能占用一个或多个字节,这取决于它所属的字符集和编码方式。
例如,在ASCII码中,一个英文字母(不分大小写)为一个字节,一个中文汉字为两个字节。在UTF-8编码中,一个英文字母为一个字节,一个中文汉字为三个字节。在Unicode编码中,一个英文字母或一个中文汉字都为两个字节。这些编码方式都有各自的优缺点,你可以根据你的需求和场景来选择合适的编码方式。
4个节点流(也称为文件流)
- FileInputStream
- FileOutputStream
- FileReader
- FileWriter
//需求:读取hello.txt中的内容,显示在控制台上。
//异常使用throws的方式处理,不太合适。见test2()
public void test1() throws IOException {
//1.创建File类的对象,对应着hello.txt文件
File file = new File("hello.txt");
//2.创建输入型的字符流,用于读取数据
FileReader fr = new FileReader(file);
//3.读取数据,并显示在控制台上
//方式1
// int data = fr.read();
// while (data!=-1){
// System.out.print((char)data);
// data=fr.read();
// }
//方式2
int data;
while ((data=fr.read())!=-1){
System.out.print((char) data);
}
//4.流资源的关闭操作(必须要关闭,否则会内存泄漏)
fr.close();
}
/*
需求:读取hello.txt中的内容,显示在控制台上。
使用try-catch-finally的方式处理异常。确保流一定可以关闭,避免内存泄瀛
*/
public void test2(){
FileReader fr = null;
try {
//1.创建File类的对象,对应着hello.txt文件
File file = new File("hello.txt");
//2.创建输入型的字符流,用于读取数据
fr = new FileReader(file);
//3.读取数据,并显示在控制台上
int data;
while ((data=fr.read())!=-1){
System.out.print((char) data);
}
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
//4.流资源的关闭操作(必须要关闭,否则会内存泄漏)
try {
if (fr!=null)//避免没创建成功,关闭导致空指针
fr.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
/*
需求:读取hello.txt中的内容,显示在控制台上。
对test2()进行优化,每次读取多个字符存放到字符数组中,减少了与磁盘交互的次数,提升效率。
*/
public void test3(){
FileReader fr = null;
try {
//1.创建File类的对象,对应着hello.txt文件
File file = new File("hello.txt");
//2.创建输入型的字符流,用于读取数据
fr = new FileReader(file);
//3.读取数据,并显示在控制台上
char[] cbuffer = new char[5];
int len;//读取到的字符数
while ((len=fr.read(cbuffer))!=-1){
for (int i = 0; i < len; i++) {
System.out.print(cbuffer[i]);
}
}
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
//4.流资源的关闭操作(必须要关闭,否则会内存泄漏)
try {
if (fr!=null)//避免没创建成功,关闭导致空指针
fr.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
/*
需求:将内存中的数据写出到指定的文件中
*/
public void test4() {
FileWriter fw = null;
try {
//1.创建File类的对象,指明要写出的文件的名称
File file = new File("info.txt");
//2.创建输出流
//fw = new FileWriter(file);表示文件覆盖
fw = new FileWriter(file,true);//true:表示在后面追加
//在现有的文件基础上,追加内容使用的构造器:
//3.写出的具体过程
//输出的方法: write (String str) / write(char[ ] cdata)
fw.write("I Love U \n");
fw.write("You love him \n");
fw.write("I'm sorry... \n");
System.out.println("输出成功");
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
//4.关闭资源
try {
fw.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
3.FileReader \ FileWriter 的使用3.1执行步骤;
第1步:创建读取或写出的File类的对象
第2步:创建输入流或输出流
第3步:具体的读入或写出的过程。
读入: read(char[ ] cbuffer)
写出: write(String str) / write(char[ ] cbuffer ,0,len)第4步:关闭流资源,避免内存泄漏
//需求:复制一份hello.txt文件,命名为hello_copy.txt
public void test5(){
FileReader fileReader = null;
FileWriter fileWriter = null;
try {
//1.创建File类的对象 2个
File srcFile = new File("hello.txt");
File destFile = new File("hello_copy.txt");
//2.创建输入流、输出流
fileReader = new FileReader(srcFile);
fileWriter = new FileWriter(destFile);
//3.数据的读入和写出的过程
char[] cbuffer = new char[5];
int len;//记录每次读入到cbuffer中的字符的个数
while ((len=fileReader.read(cbuffer))!=-1){
fileWriter.write(cbuffer,0,len);//写入char[] cbuffer的从0到len字符,左闭右开
}
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
//4.关闭流资源
try {
if (fileWriter!=null)
fileWriter.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
try {
if (fileReader!=null)
fileReader.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
3.2注意点:
因为涉及到流资源的关闭操作,所以出现异常的话,需要使用try-catch-finally的方式来处理异常
- 对于输入流来讲,要求File类的对象对应的物理磁盘上的文件必须存在。否则,会报FileNotFoundException
- 对于输出流来讲,File类的对象对应的物理磁盘上的文件可以不存在。
- 如果此文件不存在,则在输出的过程中,会自动创建此文件,并写出数据到此文件中。
- 如果此文件存在,使用FileWriter(File file)或FileWriter(File file,false):
输出数据过程中,会新建同名的文件对现有的文件进行覆盖。
FileWriter(File file , true)︰输出数据过程中,会在现有的文件的末尾追加写出内容。
//需求:复制一份playgirl.jpg文件,命名为playgirl_copy.jpg
//复制失败!因为字符流不适合用来处理非文本文件。
public void test6(){
FileReader fileReader = null;
FileWriter fileWriter = null;
try {
//1.创建File类的对象 2个
File srcFile = new File("playgirl.jpg");
File destFile = new File("playgirl_copy.jpg");
//2.创建输入流、输出流
fileReader = new FileReader(srcFile);
fileWriter = new FileWriter(destFile);
//3.数据的读入和写出的过程
char[] cbuffer = new char[5];
int len;//记录每次读入到cbuffer中的字符的个数
while ((len=fileReader.read(cbuffer))!=-1){
fileWriter.write(cbuffer,0,len);//写入char[] cbuffer的从0到len字符,左闭右开
}
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
//4.关闭流资源
try {
if (fileWriter!=null)
fileWriter.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
try {
if (fileReader!=null)
fileReader.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
4.FileInputStream \ File0utputstream的使用
4.1执行步骤:
第1步:创建读取或写出的File类的对象
第2步:创建输入流或输出流
第3步:具体的读入或写出的过程。
读入:read(byte[] buffer)
写出: write(byte[] buffer ,0,len)
第4步:关闭流资源,避免内存泄漏
//需求:复制一份playgirl.jpg文件,命名为playgirl_copy.jpg。
public void test1(){
FileInputStream fileInputStream = null;
FileOutputStream fileOutputStream = null;
try {
//1.创建File类的对象 2个
File srcFile = new File("playgirl.jpg");
File destFile = new File("playgirl_copy.jpg");
//2.创建输入流、输出流
fileInputStream = new FileInputStream(srcFile);
fileOutputStream = new FileOutputStream(destFile);
//3.数据的读入和写出的过程
byte[] buffer = new byte[1024];//1kb
int len;//记录每次读入到buffer中的字节的个数
while ((len=fileInputStream.read(buffer))!=-1){
fileOutputStream.write(buffer,0,len);//写入byte[] buffer的从0到len字符,左闭右开
}
} catch (IOException e) {
e.printStackTrace();
} finally {
//4.关闭流资源
if (fileOutputStream!=null) {
try {
fileOutputStream.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
if (fileInputStream!=null) {
try {
fileInputStream.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}
4.2注意点:
- 在3.2 注意点的基础之上,看其他的注意点。
- 对于字符流,只能用来操作文本文件,不能用来处理非文本文件的。
- 对于字节流,通常是用来处理非文本文件的。但是,如果涉及到文本文件的复制操作,也可以使用字节流。
说明:
文本文件:.txt . .java . .c、.cpp、.py等
非文本文件: .doc、.xls 、 .jpg 、 .pdf、.mp3、 .mp4、.avi等
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?