信仰:一个人走得远了,就会忘记自己为了什么而出发,希望你可以不忘初心,不要随波逐流,一直走下去
欢迎关注点赞收藏留言
本文由 程序喵正在路上 原创,CSDN首发!
系列专栏:Java从入门到入土
首发时间:2022年7月8日
? 如果觉得博主的文章还不错的话,希望小伙伴们三连支持一下哦
常用的I/O处理方式 之前我们学习了 InputStream 类、OutputStream 类、Reader 类和 Writer 类,所有流的操作类都是它们其中某个类的子类。但是这 4 个类只定义了操作流的方法,并没有具体的方法实现。
阅读指南
- 常用的I/O处理方式
- ? 文件类
- 创建文件类
- File类的常用方法
- ? 文件的字节输入/输出流
- 创建文件字节输入流
- 创建文件字节输出流
- 文件字节输入/输出流的应用
- 1. 创建FileInAndOut类
- 2. loadConfig()方法
- 3. putConfig()方法
- ? 文件的字符输入/输出流
- 创建文件字符输入流
- 创建文件字符输出流
- 文件字符输入/输出流的应用
- 1. 创建FileInAndOutChar类
- 2. readFile()方法
- 3. writeFile()方法
- ? 带缓存的输入/输出流
- BufferedInputStream 与 BufferedOutputStream 类
- BufferedReader 与 BufferedWriter 类
- ? 对象序列化
- 文件及文件夹操作
- ? 复制文件
- ? 复制文件夹
- ? 删除文件
- ? 分行写入文件
要处理文件或音频等数据流,必须使用指定设备的数据流类
? 文件类 在开始使用数据流之前,首先介绍有关 File 文件类的使用方法,这是因为数据流可以将数据写入到文件中,另外,文件也是数据流最常用的数据媒体。
File 类用于封装系统的文件和目录的相关信息,如文件大小、修改时间、文件路径等。
创建文件类
创建 File 类可以使用它的构造方法,下面介绍一下该类的常用构造方法。
(1) File(String pathname) 方法
该构造方法通过指定的文件路径字符串来创建一个新的 File 实例对象。
语法如下:
new File(filePath);
filePath:文件路径字符串,包括文件名称,如 “C:/test.txt”。
(2) File(String parent, String child) 方法
该构造方法根据指定的父路径字符串和子路径字符串(包括文件名称)创建 File 类的实例对象。
语法如下:
new File(parent, child);
parent:父路径字符串,如 “D:/doc/”。
child:子路径字符串,如 “test.txt”。
(3)File(File parent, String child)方法
该构造方法根据指定的File类的父路径和字符串类型的子路径(包括文件名称)创建File类的实例对象。
语法如下:
new File(parent, child);
? parent:父路径对象,如new File(“D:/demo/”)。
? child:子路径字符串,例如 “help.txt”。
File类的常用方法
File 类是对文件和文件夹的抽象,包含文件和文件夹的多种属性和操作方法。
File 类的常用方法如下表所示。
返回类型 | 方法名称 | 说明 |
---|---|---|
String | getName() | 获取文件名称 |
String | getParent() | 获取文件的父路径字符串 |
String | getPath() | 获取文件的相对路径字符串 |
String | getAbsolutePath() | 获取文件的绝对路径字符串 |
boolean | exists() | 判断文件或文件夹是否存在 |
boolean | isFile() | 判断是不是文件类型 |
boolean | isDirectory() | 判断是不是文件夹类型 |
boolean | isAbsolute() | 判断是不是绝对路径 |
boolean | delete() | 删除文件或文件夹,如果删除成功,返回结果为 true |
boolean | mkdir() | 创建文件夹,如果创建成功,返回结果为 true |
boolean | mkdirs() | 创建路径中包含的所有父文件夹和子文件夹,如果所有父文件夹和子文件夹都成功创建,返回结果为 true |
boolean | setReadOnly() | 设置文件或文件夹的只读属性 |
long | length() | 获取文件的长度 |
long | lastModified() | 获取文件的最后修改日期 |
String[] | list() | 获取文件夹中的文件和子文件夹的名称,并存放到字符串数组中 |
File[] | listFiles() | 获取文件夹中的文件和子文件夹的名称,并存放到 File 类型的数组 |
首先,我们在桌面创建一个 txt 文件用来测试,然后创建一个 GetFileInfo 类。编写主方法,在主方法中根据指定文件路径创建 File 文件类的实例对象,并将文件的各种属性输出到控制台。
import java.io.File;
import java.util.Date;
public class GetFileInfo {
public static void main(String[] args) {//根据开发环境指定文件路径
String filePath = "C:\\Users\\15269\\Desktop\\test.txt";
//创建文件对象
File file = new File(filePath);
//输出文件属性
System.out.println("文件名称:" + file.getName());
System.out.println("文件是否存在:" + file.exists());
System.out.println("文件的相对路径:" + file.getPath());
System.out.println("文件的绝对路径:" + file.getAbsolutePath());
System.out.println("文件上级路径:" + file.getParent());
System.out.println("文件大小:" + file.length() + "B");
System.out.println("是否是文件类型:" + file.isFile());
System.out.println("是否是文件夹类型:" + file.isDirectory());
System.out.println("文件是否可以读取:" + file.canRead());
System.out.println("文件是否可以写入:" + file.canWrite());
System.out.println("文件是否可执行:" + file.canExecute());
System.out.println("文件最后修改时间:" + new Date(file.lastModified()));
}
}
该实例的运行结果如下:
文章图片
? 文件的字节输入/输出流 在程序运行期间,大部分数据都是在内存中进行操作的,当程序结束或关闭时,这些数据将完全消失,但是有些数据需要永久保存,如程序的配置信息、日志信息等。那么我们该怎么办呢?
使用文件输入/输出流,可以和指定的文件建立关联,然后把需要永久保存的数据输出到文件中,程序在下次运行时,可以从文件中取回这些数据。
创建文件字节输入流
文件字节输入流可以从指定路径的文件中读取字节数据。文件字节输入流继承自 InputStream 类,并实现了读取输入流的各种方法。要使用文件字节输入流,必须使用构造方法创建它的实例对象。
创建文件字节输入流的常用构造方法如下。
(1) FileInputStream(File file) 方法
使用 File 类型的文件对象创建 FileInputStream 类的实例对象。
语法如下:
new FileInputStream(file);
file:File 文件类型的实例对象。
(2) FileInputStream(String name) 方法
根据指定的文件名称和路径,创建 FileInputStream 类的实例对象。
语法如下:
new FileInputStream(filePath);
filePath:文件的绝对路径或相对路径。
创建文件字节输出流
文件字节输出流关联指定路径的文件,数据通过文件字节输出流以字节为单位输出并保存到文件中。字节文件输出流继承自 OutputStream 类,并实现了输出数据的各种方法。要使用文件字节输出流,必须使用构造方法创建它的实例对象。
创建文件字节输出流的常用构造方法如下。
(1) FileOutputStream(File file) 方法
该构造方法使用 File 类型的文件对象,创建与该文件关联的 FileOutputStream 类的实例对象。
语法如下:
new FileOutputStream(file);
file:File 文件类型的实例对象。
(2) FileInputStream(String name) 方法
该构造方法根据指定的文件名称和路径,创建关联该文件的 FileOutputStream 类的实例对象。
语法如下:
new FileOutputStream(filePath);
filePath:文件的绝对路径或相对路径。
文件字节输入/输出流的应用
字节输/输出流的父类 InputStream 类和 OutputStream 类已经定义了访问数据流的基本方法,文件字节输入/输出流针对文件类型实现了这些访问数据流的方法。
下面我们通过一个实例来了解如何使用文件字节输入/输出流读写指定的文本文件。
本实例在第一次运行时,将运行次数、运行时间和操作系统的名称保存到配置文件中,在第二次运行时,会从配置文件中读取上次运行实例的信息。
1. 创建FileInAndOut类 创建 FileInAndOut 类,定义类的运行次数、运行时间、操作系统名称等属性,然后编写主方法,在主方法中调用 loadConfig() 方法从 “myProgram.cfg” 配置文件中获取程序上次运行时的属性信息。如果没有配置文件或者配置文件中没有内容,将在控制台输出 “这是程序第一次运行,其他信息还没有初始化。” 的信息,否则输出程序上次运行时定义的属性信息,并且将本次程序运行的属性通过调用 putConfig() 方法保存到配置文件中。
import java.io.File;
import java.util.Date;
public class FileInAndOut {
private static String filePath = "./myProgram.cfg";
private static File file = new File(filePath);
//程序运行次数
private static int runCount = 0;
//上次运行时间
private static String date = String.format("%tF %
2. loadConfig()方法 定义装载配置信息的 loadConfig() 方法,该方法首先判断配置文件是否存在,如果不存在配置文件,就调用 createNewFile() 方法创建一个。然后创建文件字节输入流对象 fis,并且从输入流中读取配置文件的属性配置信息,通过解析属性配置信息,更新程序的属性值,关键代码如下。
//装载配置信息
private static void loadConfig() {
try {
//如果文件不存在
if (!file.exists())
//创建新文件
file.createNewFile();
byte[] data = https://www.it610.com/article/new byte[64];
//创建文件字节输入流
FileInputStream fis = new FileInputStream(file);
//在循环中读取输入流的数据
int rs = 0;
while ((rs = fis.read(data))> 0) {
dataStr += new String(data, 0, rs);
}if(!dataStr.isEmpty()){
//使用读取的数据初始化属性信息
String[] sets = dataStr.split(",");
runCount = Integer.parseInt(sets[0]);
date = sets[1];
os = sets[2];
}//关闭输出流
fis.close();
} catch (Exception e) {
e.printStackTrace();
}
}
3. putConfig()方法 定义保存配置信息的 putConfig() 方法,该方法首先判断配置文件是否存在,如果不存在就创建一个。然后将程序的属性使用 “,” 符号连接成字符串,并输出到配置文件中,最后刷新并关闭文件字节输出流,关键代码如下。
//保存配置信息
private static void putConfig(){
String dataStr;
try{
//如果文件不存在
if(!file.exists())
//创建新文件
file.createNewFile();
dataStr = (runCount+1) + "," + date + "," + os;
byte[] data = https://www.it610.com/article/dataStr.getBytes();
FileOutputStream fout = new FileOutputStream(file);
//将数据写入输出流
fout.write(data);
//刷新缓冲区
fout.flush();
//关闭输出流
fout.close();
}catch (Exception e){
e.printStackTrace();
}
}
第一次运行该实例,结果如下:
文章图片
第二次运行该实例,结果如下:
文章图片
? 文件的字符输入/输出流 文件的字符输入/输出流和文件的字节输入/输出流有相同的功能,但是传送数据的方式不一样,字节流以字节为单位传送数据,可以是任何类型的数据,如文本、音频、视频、图片等,而字符流以字符为单位传送数据,只能传送文本类型的数据。
创建文件字符输入流
文件字符输入流可以从指定路径的文件中读取字符数据。文件字符输入流继承自 Reader 类,并实现了读取字符输入流的各种方法。要使用文件字符输入流,必须使用构造方法创建它的实例对象。
创建文件字符输入流的常用构造方法如下。
(1) FileReader(File file) 方法
使用 File 类型的文件对象创建 FileReader 类的实例对象。
语法如下:
new FileReader(file);
file:File 文件类型的实例对象。
(2) FileReader(String name) 方法
根据指定的文件名称和路径,创建 FileReader 类的实例对象。
语法如下:
new FileReader(filePath);
filePath:文件的绝对路径或相对路径。
创建文件字符输出流
文件字符输出流关联指定路径的文件,数据通过文件字符输出流以字符为单位输出并保存到文件中。文件字符输出流继承自 Writer 类,并实现了向文件输出数据的各种方法。要使用文件字符输出流,必须使用构造方法创建它的实例对象。
创建文件字符输出流的常用构造方法如下。
(1) FileWriter(File file) 方法
使用 File 类型的文件对象,创建与该文件关联的 FileWriter 类的实例对象。
语法如下:
new FileWriter(file);
file:File 文件类型的实例对象。
(2) FileWriter(String name) 方法
根据指定的文件名称和路径,创建与该文件关联的 FileWriter 类的实例对象。
语法如下:
new FileWriter(filePath);
filePath:文件的绝对路径或相对路径。
文件字符输入/输出流的应用
文件字符输入/输出流的父类 Reader 和 Writer 类已经定义了访问数据流的基本方法,文件字符输入/输出流针对文件类型实现了这些访问数据流的方法。
下面我们通过一个实例来了解如何使用文件输入流和文件输出流,读写指定的文本文件。
本实例创建了关联程序源代码文件(即 FileInAndOutChar.java 文件)的文件字符输入流,通过该输入流读取文件信息到 StringBuilder 类的实例对象(即字符串生成器对象)strBuilder 中,并在控制台显示 strBuilder 对象的内容,然后将这些内容通过文件字符输出流保存到实例所在路径下的 FileInAndOutChar.bak 文件中。
温馨提示:
如果你将 FileInAndOutChar.java 类创建在其他包中,需要根据自己定义的路径进行修改。
1. 创建FileInAndOutChar类 创建 FileInAndOutChar 类,编写主方法,在主方法中定义 StringBuilder 类的实例对象 strBuilder,调用 readFile() 方法读取程序源代码到 strBuilder 对象中,然后把 strBuilder 对象的内容输出到控制台,并通过 writeFile() 方法保存到 FileInAndOutChar.bak 文件中,关键代码如下。
public static void main(String[] args) {
StringBuilder stringBuilder = new StringBuilder();
//调用读取字符输入流数据的方法
readFile(stringBuilder);
System.out.println(stringBuilder);
//调用写入数据到字符输出流的方法
writeFile(stringBuilder);
}
2. readFile()方法 编写读取字符输入流数据的 readFile() 方法,在该方法中创建文件字符输入流 fReader,通过该文件字符输入流获取文件的内容到 strBuilder 对象中,关键代码如下。
//读取字符输入流数据
private static void readFile(StringBuilder stringBuilder) {
try{
String filePath = "D:\\IDEA\\idea_Demo\\IO流\\FileInAndOutChar.java";
File file = new File(filePath);
//创建文件字符输入流
FileReader fileReader = new FileReader(file);
char[] data = https://www.it610.com/article/new char[512];
int rs = 0;
while((rs = fileReader.read(data))> 0){
//在循环中读取数据
stringBuilder.append(data,0,rs);
}//关闭流
fileReader.close();
}catch (Exception e){
e.printStackTrace();
}
}
3. writeFile()方法 编写输出数据到文件字符输出流的 writeFile() 方法,在方法中创建文件字符输出流 fWriter,然后将 strBuilder 对象中的内容通过文件字符输出流保存到实例所在路径中的 FileInAndOutChar.bak 文件中,关键代码如下。
//写入数据到字符输出流
private static void writeFile(StringBuilder stringBuilder) {
try {
String filePath = "D:\\IDEA\\idea_Demo\\IO流\\FileInAndOutChar.bak";
File file = new File(filePath);
//创建文件字符输出流
FileWriter fileWriter = new FileWriter(file);
//将数据写入输出流
fileWriter.write(stringBuilder.toString());
//关闭流
fileWriter.close();
} catch (Exception e) {
e.printStackTrace();
}
}
该实例的运行结果如下:
控制台会读取本类的代码输出
文章图片
同时将读取到的数据写到新生成的 FileInAndOutChar.bak 文件中
文章图片
? 带缓存的输入/输出流 缓存可以说是 I/O 的一种性能优化。缓存流为 I/O 流增加了内存缓存区。有了缓存区,使得在流上执行 skip()、mark() 和 reset() 等方法都成为可能。
BufferedInputStream 与 BufferedOutputStream 类
BufferedInputStream 类可以对任何 InputStream 类进行带缓存区的包装,以达到性能的优化
BufferedInputStream 类有两个构造函数:
●
BufferedInputStream(InputStream in);
●
BufferedInputStream(InputStream in, int size);
第一种形式的构造函数创建了一个带有 32 字节的缓存流;第二种形式的构造函数按指定的大小来创建缓存区。一个最优的缓存区的大小,取决于它所在的操作系统、可用的内存空间及机器配置。从构造函数可以看出,BufferedInputStream 对象位于 InputStream 类对象之前。
下图描述了字节数据读取文件的过程
文章图片
使用 BufferedOutputStream 输出信息和往 OutputStream 输出信息完全一样,只不过 BufferedOutputStream 有一个用来将缓存区的数据强制输出完的 flush() 方法。
BufferedOutput Stream类也有两个构造方法:
●
BufferedOutputStream(OutputStream in);
●
BufferedOutputStream(OutputStream in , int size);
第一种构造函数创建一个 32 字节的缓存区,第二种形式以指定的大小来创建缓存区。
注意
flush() 方法用于即使缓存区没有满的情况下,也将缓存区的内容强制写入到外设,习惯上称这个过程为刷新。flush() 方法只对使用缓存区的 OutputStream 类的子类有效。当调用 close() 方法时,系统在关闭流之前,也会将缓存区中的信息刷新到磁盘文件中。
BufferedReader 与 BufferedWriter 类
BufferedReader 类与 BufferedWriter 类分别继承 Reader 类与 Writer 类。这两个类同样具有内部缓存机制,并可以以行为单位进行输入和输出。
BufferedReader 类常用的方法如下
● read() 方法:读取单个字符
● readLine() 方法:读取一个文本行,并将其返回为字符串。若无数据可读,则返回null
BufferedWriter 类中的方法都返回 void,常用的方法如下
● write(String s, int off, int len) 方法:写入字符串的某一部分
● flush() 方法:刷新该流的缓存
● newLine() 方法:写入一个行分隔符
在使用 BufferedWriter 类的 write() 方法时,数据并没有被立刻写入到输出流中,而是首先进入缓存区中。如果想立刻将缓存区中的数据写入输出流中,一定要调用 flush() 方法。
实例
向指定的磁盘文件中写入数据,并通过 BufferedReader 类将文件中的信息分行显示。
import java.io.*;
public class Student {
public static void main(String[] args) {
//定义字符数组
String content[] = {"好久不见", "最近好吗", "常联系"};
//创建文件对象
File file = new File("D:/word.txt");
try {
//创建FileWriter类对象
FileWriter fw = new FileWriter(file);
//创建BufferedWriter类对象
BufferedWriter bufw = new BufferedWriter(fw);
//循环遍历数组
for (int k = 0;
k < content.length;
k++) {
//将字符串数组中的元素写入到磁盘文件中
bufw.write(content[k]);
//将数组中的单个元素以单行的形式写入文件
bufw.newLine();
}//将BufferedWriter流关闭
bufw.close();
//将FileWriter流关闭
fw.close();
} catch (Exception e) {
e.printStackTrace();
}try {
//创建FileReader类对象
FileReader fr = new FileReader(file);
//创建BufferedReader类对象
BufferedReader bufr = new BufferedReader(fr);
//创建字符串对象
String s = null;
int i = 0;
//如果文件的文本行数不为null,则进入循环
while ((s = bufr.readLine()) != null) {
i++;
System.out.println("第" + i + "行: " + s);
}//将BufferedReader流关闭
bufr.close();
//将FileReader流关闭
fr.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
运行结果如下
文章图片
? 对象序列化 程序在运行的过程中可能需要保存数据,对于基本的数据类型,如 int、float、char 等,可以简单地保存到文件中,程序下次启动时,可以读取文件中的数据初始化程序。
但是对于复杂的对象类型,如果需要永久保存,则需要把对象中不同的属性分解为基本数据类型,然后分别保存到文件中,当程序再次运行时,需要建立新的对象,然后从文件中读取与对象有关的所有数据,再使用这些数据分别为对象的每个属性初始化。
Java 的 ObjectInput 接口与 ObjectOutput 接口分别继承了 DataInput 接口和 DataOutput 接口,提供了对基本数据类型和对象序列化的方法。
使用对象序列化功能,可以非常方便地将对象写入输出流,或者从输入流读取对象数据。
下面将介绍 ObjectInput 接口与 ObjectOutput 接口中定义的对象序列化和反序列化方法。
? readObject() 反序列化方法
所谓反序列化,就是从输入流中获取序列化的对象数据,用这些数据生成新的 Java 对象。该方法定义在 ObjectInput 接口中,由 ObjectInputStream 类实现。
语法如下:
Object object = readObject();
? object:Java 对象
注意
使用该方法获取的序列化对象是 Object 类型的,必须执行强制类型转换后才能使用
? writeObject() 序列化方法
序列化就是将对象写入到输出流,这个输出流可以是文件输出流、网络输出流或其他数据输出流。该方法定义在 ObjectOutput 接口中,由 ObjectOutputStream 类实现。
语法如下:
writeObject(object)
? object:将要序列化的对象
实例
创建 Worker 工人类,将该类的实例对象序列化到文件字节输出流,然后从文件字节输入流中反序列化该类的实例对象,并输出该对象的内容。
? 创建 Worker 类,该类必须实现 Serializable 接口,然后定义姓名、性别、年龄三个属性,并提供访问属性的方法,代码如下
import java.io.*;
public class Worker implements Serializable {
//定义表示姓名的字符串变量
private String name;
//定义表示性别的字符串变量
private String gender;
//定义表示年龄的int变量
private int age;
public String getName() {
return name;
}public void setName(String name) {
this.name = name;
}public String getGender() {
return gender;
}public void setGender(String gender) {
this.gender = gender;
}public int getAge() {
return age;
}public void setAge(int age) {
this.age = age;
}
}
? 创建 ObjectSerializable 类,编写主方法,在主方法中创建工人对象(即 Worker 类的实例对象),设置该对象的姓名、性别和年龄属性,然后将该对象序列化到 worker.dat 文件中,这样就实现了对象到文件的序列化。为验证对象序列化的内容,再从 worker. dat 文件中反序列化工人对象,并将对象的属性输出到控制台,代码如下
import java.io.*;
public class ObjectSerializable {
public static void main(String[] args) {
//将工人对象序列化
try {
//创建工人对象
Worker worker = new Worker();
//设置对象属性
worker.setName("青龙");
worker.setGender("男");
worker.setAge(24);
//创建FileOutputStream对象
FileOutputStream fout = new FileOutputStream("./worker.dat");
//创建ObjectOutputStream对象
ObjectOutputStream oops = new ObjectOutputStream(fout);
//将对象序列化
oops.writeObject(worker);
} catch (Exception e) {
e.printStackTrace();
}//反序列化工人对象
try {
//创建FileInputStream对象
FileInputStream fis = new FileInputStream("./worker.dat");
//创建ObjectInputStream对象
ObjectInputStream oi = new ObjectInputStream(fis);
//对象反序列化
Worker newWorker = (Worker) oi.readObject();
//输出对象信息
System.out.println("姓名: " + newWorker.getName());
System.out.println("性别: " + newWorker.getGender());
System.out.println("年龄: " + newWorker.getAge());
} catch (Exception e) {
e.printStackTrace();
}
}
}
? 运行本实例,将在实例所在的文件夹中创建 worker.dat 文件,并且在控制台输出以下信息
文章图片
文件及文件夹操作 通过 I/O 技术可以实现文件管理,如复制文件、删除文件、创建文件等。这些操作在实际开发中应用得非常广泛。下面我们将介绍通过 I/O 技术实现的各种文件及文件夹操作。
? 复制文件 复制文件是将文件内容复制到指定位置的新文件中,类似于操作系统中的复制文件功能。在复制文件的过程中,如果目标文件不存在,则以目标文件名为名创建新的文件,并将原文件内容复制到该文件中,否则覆盖目标文件。
实例
创建类 FileCopy,在该类的主方法中编写代码,实现将该类中的代码复制到 FileCopyrepeat 类中。
import java.io.*;
public class FileCopy {
public static void main(String[] args) {
//定义要进行复制的文件路径
String sfpath = "Solution/FileCopy.java";
//定义复制后文件的保存路径
String dfpath = "Solution/FileCopyRepeat.java";
//创建要进行复制的文件对象
File sFile = new File(sfpath);
//创建保存复制后的文件对象
File dFile = new File(dfpath);
try {
//新建文件
dFile.createNewFile();
//定义FileInputStream对象
FileInputStream fis = new FileInputStream(sFile);
//定义FileOutputStream对象
FileOutputStream fout = new FileOutputStream(dFile);
//定义byte数组
byte[] date = new byte[512];
int rs = -1;
//如果没有读到文件末尾
while ((rs = fis.read(date)) > 0) {
//向流中写数据
fout.write(date, 0, rs);
}//关闭流
fout.close();
fis.close();
System.out.println("文件复制成功!");
} catch (Exception e) {
e.printStackTrace();
}
}
}
? 复制文件夹 复制文件夹要比复制文件复杂一些,因为文件夹内可能包含很多文件甚至其他文件夹,必须对它们分别执行复制操作。
实例
本实例的主要功能是实现文件夹的复制。前面介绍了文件的复制,文件夹的复制方法和文件的复制方法基本类似。
? 创建 FolderCopy 类,在该类中创建 copy() 方法,该方法接收文件数组和目标文件夹两个参数,如果目标文件夹不存在,则调用 mkdir() 方法创建文件夹,然后用循环语句判断文件数组中的每个文件对象。如果文件对象是文件类型,则复制该文件到目标文件夹中,如果该文件对象是文件夹类型,则调用该方法的 listFiles() 方法获取该文件夹的文件数组(即文件夹的文件列表),创建新的目标文件夹对象,再通过文件数组和目标文件夹嵌套调用该方法,这样就能把这个文件夹中所有内容复制到另外一个文件夹中。
import java.io.*;
public class FolderCopy {
private static void copy(File[] s, File d) {
//如果文件夹不存在
if (!d.exists()) {
//建立新的文件夹
d.mkdir();
}for (int i = 0;
i < s.length;
i++) {
//如果是文件类型就复制文件
try {
FileInputStream fis = new FileInputStream(s[i]);
FileOutputStream fout = new FileOutputStream(new File(d.getPath() + File.separator + s[i].getName()));
int count = fis.available();
byte[] data = https://www.it610.com/article/new byte[count];
if ((fis.read(data)) != -1) {
//复制文件内容
fout.write(data);
}//关闭流
fout.close();
fis.close();
} catch (Exception e) {
e.printStackTrace();
}//如果是文件夹类型
if (s[i].isDirectory()) {
//在目标文件夹中创建相同的文件夹
File des = new File(d.getPath() + File.separator + s[i].getName());
//递归调用本身
copy(s[i].listFiles(), des);
}
}
}
? 创建主方法,在方法中建立源文件夹和目标文件夹两个对象,调用源文件夹的 listFiles() 方法获取文件数组(即文件列表),通过这个文件数组和目标文件夹调用 copy() 方法完成文件夹的复制,关键代码如下
//主方法
public static void main(String[] args) {
File sourFile = null, desFile = null;
//可以修改源文件夹路径
String sourFolder = "./sourceFolder";
//可以修改目标文件夹路径
String desFolder = "./desFolder";
sourFile = new File(sourFolder);
if (!sourFile.isDirectory() || !sourFile.exists()) {
System.out.println("源文件夹不存在");
}
desFile = new File(desFolder);
desFile.mkdir();
//调用copy()方法
copy(sourFile.listFiles(), desFile);
}
? 在本实例的当前文件夹中建立 sourceFolder 文件夹,给这个文件夹复制一些文件或其他文件夹,然后运行本实例,sourceFolder 文件夹的内容将全部复制到 desFolder 文件夹中。
? 删除文件 File 类的 delete() 方法用于删除指定的文件,但是必须使用目标文件路径创建一个 File 类的实例对象,然后调用该实例对象的 delete() 方法删除指定文件。
? 创建 FileDelete 类,编写 delFile() 方法,该方法接收一个文件对象参数,即 File 类的实例对象,调用文件对象的 exists() 方法判断文件是否存在,如果不存在,则在控制台输出 “文件不存在” 的提示信息,如果文件存在,则调用 delete() 方法删除该文件,关键代码如下。
public class FileDelete {
public static void delFile(File file) {
//判断文件是否存在
if (!file.exists()) {
System.out.println("文件不存在");
return;
}//调用delete()方法
boolean rs = file.delete();
//如果文件删除成功
if (rs) {
System.out.println("文件删除成功");
} else {
System.out.println("文件删除失败");
}
}
}
? 编写主方法,在主方法中创建将要删除的文件的 File 类实例对象,然后调用 delFile() 方法删除该文件,关键代码如下。
public static void main(String[] args) {
//定义要删除的文件
String filePath = "Solution\\FileDelete.java";
//创建该文件对象
File file = new File(filePath);
//调用删除文件的方法
delFile(file);
}
? 运行本实例后,刚刚你写的文件就没有了
? 分行写入文件 FileWriter 类可以向文件写入字符数据,如果将 FileWriter 类封装到 BufferedWriter 类的缓冲字符流中,则能够实现缓冲字符输出流,并且可以通过该输出流的 newLine() 方法实现数据的分行写入
? 创建 LineWriterData 类,编写主方法,在主方法中定义要写入数据的文件的路径,通过该路径建立一个 FileWriter 类的实例对象,再使用该对象创建一个 BufferedWriter 类的实例对象(即缓冲数据流对象),调用缓冲数据流对象的 writer() 方法把数据写入到文件中,然后调用 newLine() 方法写入换行符,调用 flush() 方法把内存中的内容写入到文件中并输出提示信息,关键代码如下
import java.io.*;
public class LineWriterData {
public static void main(String[] args) {
//定义文件地址
String filePath = "Solution\\File.txt";
File file = new File(filePath);
try {
//创建文件字符输出流
FileWriter fw = new FileWriter(file);
//使用缓冲数据流封装输出流
BufferedWriter bw = new BufferedWriter(fw);
//写入数据到输出流
bw.write("CSDN".toCharArray());
//写入换行符
bw.newLine();
bw.write("好好学习");
bw.newLine();
bw.write("天天向上");
bw.newLine();
//刷新缓冲区
bw.flush();
System.out.println("数据已经写入File.txt文件中");
} catch (Exception e) {
e.printStackTrace();
}
}
}
? 运行本实例,控制台将输出 “数据已经写入 File.txt 文件中” 的提示信息,同时在本实例的当前路径下会创建 File.txt 文件,其内容是分行写入的数据文件
文章图片
【Java从入门到入土|[Java] 神秘的IO流 (下)】
这次的分享就到这里啦,继续加油哦
?下期预告:Java多线程
有出错的地方欢迎在评论区指出来,共同进步,谢谢啦
推荐阅读
- Java从入门到入土|[Java] 异常的使用
- docker|云原生时代下的容器镜像安全(上)
- 程序人生|微服务的构建环境比较--Spring Cloud和Kubernetes
- 公司新来一个同事,把 @Transactional 事务注解运用得炉火纯青。。
- python|UNIX文件系统命令
- 资讯|为什么有些程序员敲代码太慢,效率太低()
- SpringBoot快速整合通用Mapper
- 数据库|Mall电商实战项目专属学习路线,主流技术一网打尽!
- java|@pathvariable 和 @Requestparam的详细区别