File类
1. File类的基本使用
File,是文件和目录路径的抽象表示 File只关注文件本身的信息,而不能操作文件里的内容
package com.wz.file03_class;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class test01 {
public static void main(String[] args) {
//通过指定路径来构建一个文件信息对象
File file = new File("D:\\Alibaba Cloud disk Download\\test.txt");
//检测文件是否存在
System.out.println(file.exists());
//获取文件的长度(大小,单位:字节)
long length = file.length();
System.out.println(length);
//获取文件最后修改的时间
long time = file.lastModified();
System.out.println(time);
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println(format.format(new Date(time)));
//获取文件权限
boolean readable = file.canRead();
boolean writeable = file.canWrite();
boolean executeable = file.canExecute();
System.out.println("read: "+readable);
System.out.println("write: "+writeable);
System.out.println("execute: "+executeable);
//获取文件的路径
String path = file.getPath();
System.out.println(path);
//获取父文件夹的路径
String parent = file.getParent();
System.out.println(parent);
//获取父文件夹对象
File parentFile = file.getParentFile();
System.out.println(parentFile);
System.out.println("------------------------");
File file1 = new File("test.txt");
System.out.println(file1.exists());
System.out.println(file1.getPath());
System.out.println(file1.getAbsolutePath());
System.out.println("------------------------");
//检测文件是否是目录
boolean isDirectory = file1.isDirectory();
System.out.println(isDirectory);
//检测文件是否是文件
boolean isFile = file1.isFile();
System.out.println(isFile);
//检测文件是否为隐藏文件
boolean isHidden = file1.isHidden();
System.out.println(isHidden);
/**
* 文件操作存在一定的逻辑,当我们要写一个文件的时候,必须要保证文件的父级目录
* 是存在的,如果不存在,则会报错
*/
File parentDir = new File("d:/test/test01");
if (!parentDir.exists()){
parentDir.mkdirs();
}
File writeFile = new File(parentDir, "user.txt");
if (!writeFile.exists()){
try {
writeFile.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
2. 递归
1. 列出一个文件夹里的所有的.class文件
package com.wz.file04_class;
import java.io.File;
import java.io.FileFilter;
public class FileDemo {
public static void main(String[] args) {
String path = "D:\\Project file\\fyOfflineCourse\\MyDay01\\out\\production";
File folder = new File(path);
findClass(folder);
}
/**
* 列出一个文件夹中所有的.class文件
*/
private static void findClass(File folder){
final FileFilter filter = new FileFilter() {
@Override
public boolean accept(File f) {
return f.getName().endsWith(".class")||f.isDirectory();
}
};
//使用文件过滤器来过滤文件,满足条件的才会在数组中出现
final File[] files = folder.listFiles(filter);
for (File file : files) {
if (file.isDirectory()){
//递归
findClass(file);
}else{
System.out.println(file.getPath());
}
}
}
}
2. 删除文件夹
/**
* 删除文件夹,需要注意一点:删除文件夹的时候,如果文件夹中存在子文件,那么文件夹
* 将无法删除,因此,删除文件夹的时候,首先需要将子文件全部删除
* @param folder 给定一个要删除的文件夹
*/
private static void deleteFolder(File folder){
/*`listFiles()` 是一个 Java 文件类(`File`)的方法
用于获取一个目录下的所有文件和子目录
该方法返回一个 `File[]` 数组
该数组包含了目录中的所有文件和子目录。*/
final File[] files = folder.listFiles();
//检验files是否为null
if (files!=null){
for (File f : files) {
//判断f是否是一个目录
if (f.isDirectory()){//是目录
deleteFolder(f);//递归
}else {
f.delete();//不是目录就直接删除
}
}
}
folder.delete();
}
该方法首先使用
listFiles()方法获取文件夹中的所有文件和子目录,并将结果存储在一个File[]数组中。然后,通过遍历数组,判断每个文件或子目录是否是一个目录。如果是目录,就递归调用
deleteFolder()方法来删除子目录。如果是文件,直接调用delete()方法删除文件。最后,删除完所有子文件和子目录后,调用
delete()方法删除文件夹本身。请注意,删除文件夹时需要注意一点:如果文件夹中存在子文件或子目录,那么文件夹将无法直接删除。因此,在删除文件夹之前,需要先删除所有子文件和子目录。以上代码中的递归调用
deleteFolder()方法就是用来删除子文件和子目录的。另外,为了确保子文件夹和子文件都被删除,我们在删除文件夹本身之前,再次调用
delete()方法删除文件夹。
3. 扫描文件
/**
* 扫描文件夹
* @param folder 给定一个扫描的文件夹
*/
public static void scanFolder(File folder){
//listFiles()用于获取一个目录下的所有文件和子目录
File[] files = folder.listFiles();
if (files!=null){
for (File f : files) {
if (f.isDirectory()){//判断f是否为目录
scanFolder(f);//递归
}else {
System.out.println(f.getPath());//不是,获取路径
}
}
}
}IO流


磁盘和内存是两个不同的设备,它们之间要实现数据的交互,就必须要建立一条通道,在Java中实现建立这样的通道的是I / O流。
Java 中的 I / O 流是按照数据类型来划分的。
分别是字节流(缓冲流、二进制数据流和对象流)、字符流
字节流
1 .OutputStreamTest输出流(写数据)
package com.wz.io01_class;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
public class OutputStreamTest {
public static void main(String[] args) {
String path = "d:/io/output.txt";
File file = new File(path);
//判断父级目录是否存在
File parentFile = file.getParentFile();
if (!parentFile.exists()){
parentFile.mkdirs();
}
//try-with-resources=>JDK1.7提供的新特性 IO流在使用了之后会自动关闭
//try-with-resources try后面的()中可以写多行代码,但是必须以分号分割开,最后一行代码的
//分号可以省略。能够写入括号中的内容必须是实现了AutoClosable接口的流的构建
try (OutputStream os = new FileOutputStream(file,true)) {
String content = "hello world!!";
final byte[] data = content.getBytes();//获取字符串的byte数据
os.write(data);//写入数据
os.flush();//强制将通道中的数据刷出,写入文件
}catch (IOException e){
e.printStackTrace();
}
}
}
以上代码是一个使用
OutputStream将数据写入文件的示例。首先,我们创建一个
File对象,表示要写入的文件。然后,使用getParentFile()方法获取父级目录,并判断该目录是否存在。如果不存在,使用mkdirs()方法创建父级目录。接下来,我们使用
FileOutputStream来创建一个输出流os,并将文件作为参数传递给它。这样就可以将数据写入文件了。在写入数据之前,我们将要写入的内容转换为字节数组
data,然后使用write()方法将数据写入文件。最后,使用flush()方法强制将通道中的数据刷新到文件中。为了确保流被正确关闭,我们使用了
try-with-resources语句。在try后面的括号中,我们创建了一个OutputStream对象,并将其赋值给os。在try代码块结束后,os将自动关闭。如果在写入数据过程中发生了异常,我们使用
catch块捕捉并打印异常信息。注意,如果要将数据追加到文件末尾而不是覆盖原有内容,可以在创建
FileOutputStream对象时传入第二个参数true,如下所示:OutputStream os = new FileOutputStream(file, true);
2. InputStreamTest输入流
package com.wz.io01_class;
import java.io.*;
public class InputStreamTest {
public static void main(java.lang.String[] args) {
File file = new File("d:/io/output.txt");
try (InputStream in = new FileInputStream(file);){
//如果文件比较大,我们需要构建一个容器,来反复读取文件内容
byte[] buffer = new byte[5];
int len;
while ((len = in.read(buffer)) != -1){
System.out.println(new java.lang.String(buffer,0, len));
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
以上代码是一个使用
InputStream从文件中读取数据的示例。首先,我们创建一个
File对象,表示要读取的文件。然后,使用FileInputStream来创建一个输入流in,并将文件作为参数传递给它。这样就可以从文件中读取数据了。在读取数据之前,我们创建了一个字节数组
buffer,用于存储读取到的数据。buffer的大小可以根据需要调整,这里设置为 5 个字节。然后,我们使用
read()方法从输入流中读取数据,并将读取到的字节数保存在变量len中。如果len的值为 -1,表示已经读取到文件末尾,循环结束。否则,我们使用new String(buffer, 0, len)将字节数组转换为字符串,并打印出来。
try-with-resources自动关闭流。
3. 利用io流进行复制
package com.wz.io01_class;
import java.io.*;
import java.nio.file.Files;
public class FileCopy {
public static void main(String[] args) {
String source = "d:/io/output.txt";
String dest = "d:/io/output01.txt";
copy(new File(source), new File(dest));
}
public static void copy(File source, File dest) {
//获取父目录
final File parentFile = dest.getParentFile();
if (!parentFile.exists()) {
parentFile.mkdirs();
}
try (InputStream in = Files.newInputStream(source.toPath());
OutputStream os = Files.newOutputStream(dest.toPath())) {
byte[] buffer = new byte[2048]; //构建一个容器来存储读取的数据
int len;
while ((len = in.read(buffer)) != -1) {
//读取多少就写多少
os.write(buffer, 0, len);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
字节流仅仅适用于读取原始数据(基本数据类型)
字符流
1. 从文件中读取数据并写入另一个文件
package com.wz.char_class;
import java.io.*;
public class ReaderTest {
public static void main(String[] args) {
//字符流的顶层父类,Reader Writer
try(Reader reader = new FileReader("d:/io/output.txt");
Writer writer = new FileWriter("d:/io/output03.txt")){
char[] buffer = new char[2048];
int len;
while ((len=reader.read(buffer))!=-1){
System.out.println(new String(buffer,0,len));
writer.write(buffer,0,len);
}
}catch (IOException e){
e.printStackTrace();
}
}
}
以上代码是一个使用字符流
Reader和Writer从文件中读取数据并写入另一个文件的示例。首先,我们创建一个
Reader对象reader,使用FileReader来读取文件"d:/io/output.txt"的内容。然后,我们创建一个Writer对象writer,使用FileWriter来写入文件"d:/io/output03.txt"。在读取和写入数据之前,我们创建了一个字符数组
buffer,用于存储读取到的数据。buffer的大小可以根据需要调整,这里设置为 2048 个字符。然后,我们使用
read()方法从输入流中读取数据,并将读取到的字符数保存在变量len中。如果len的值为 -1,表示已经读取到文件末尾,循环结束。否则,我们使用new String(buffer, 0, len)将字符数组转换为字符串,并打印出来。同时,我们使用write()方法将读取到的数据写入到输出流中。
2. 字符缓存流
package com.wz.char_class;
import java.io.*;
public class BufferedStreamDemo {
public static void main(String[] args) {
try(Reader reader = new FileReader("d:/io/output.txt");
BufferedReader br = new BufferedReader(reader)){
//读取一行数据,本质上是一个一个的读取,读取到\r\n就停止
while (true){
String s = br.readLine();
if (s == null){
break;
}
System.out.println(s);
}
}catch (IOException e){
e.printStackTrace();
}
String[] infos = {"第一条数据","第二条数据","第三条数据"};
try(Writer writer = new FileWriter("d:/io/buffer.txt");
BufferedWriter bw = new BufferedWriter(writer)){
for (String info : infos) {
bw.write(info);//写一个字符串
//bw.write('\r');
//bw.write('\n');
//bw.write("\r\n");
bw.newLine();//换行
}
}catch (IOException e){
e.printStackTrace();
}
}
}
以上代码是一个使用缓冲字符流
BufferedReader和BufferedWriter的示例。首先,在
main()方法中,我们创建一个Reader对象reader,使用FileReader来读取文件"d:/io/output.txt"的内容。然后,我们创建一个BufferedReader对象br,将reader对象传入构造方法中进行包装。在读取数据时,我们使用
readLine()方法从输入流中读取一行数据。如果读取到的数据为null,表示已经读取到文件末尾,循环结束。否则,我们将读取到的数据打印出来。为了确保流被正确关闭,我们使用了
try-with-resources语句。在try后面的括号中,我们创建了一个Reader对象,并将其赋值给reader,同时创建了一个BufferedReader对象,并将其赋值给br。在try代码块结束后,reader和br将自动关闭。在第二部分的代码中,我们创建了一个字符串数组
infos,其中包含了三条数据。然后,我们创建一个
Writer对象writer,使用FileWriter来写入文件"d:/io/buffer.txt"。接下来,我们创建一个BufferedWriter对象bw,将writer对象传入构造方法中进行包装。在写入数据时,我们使用
write()方法将字符串写入输出流中。为了实现换行效果,我们使用了newLine()方法来插入换行符。同样地,为了确保流被正确关闭,我们使用了
try-with-resources语句。在try后面的括号中,我们创建了一个Writer对象,并将其赋值给writer,同时创建了一个BufferedWriter对象,并将其赋值给bw。在try代码块结束后,writer和bw将自动关闭。请注意,
BufferedReader和BufferedWriter可以提供更高效的读写操作,因为它们会在内部维护一个缓冲区,以减少对底层流的直接访问次数。这样可以减少文件读写的开销,提高读写的效率。
应用
在一个文本文件中储存有一下信息:
张三 男 20 李四 女 22 王五 其他 23
由于在录入的时候,王五的性别录成了“其他“
现在需要将性别修正为”男“
请使用IO流的相关知识完成这个过程
package com.wz.char02_class;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
public class BufferedStreamDemo {
public static void main(String[] args) {
/*在一个文本文件中储存有一下信息
张三 男 20
李四 女 22
王五 其他 23
由于在录入的时候,王五的性别录成了“其他“
现在需要将性别修正为”男“
请使用IO流的相关知识完成这个过程*/
//构建集合存储文本集合
List<Student> students =new ArrayList<>();
try (BufferedReader reader = new BufferedReader(new FileReader("d:/io/test.txt"));){
String line;
while ((line=reader.readLine())!=null){
//根据,号分割字符串
String[] arr = line.split(",");
Student stu = new Student();
stu.setName(arr[0]);
stu.setSex(arr[1]);
stu.setAge(Integer.parseInt(arr[2]));
students.add(stu);
}
}catch (IOException e){
e.printStackTrace();
}
try(BufferedWriter writer = new BufferedWriter(new FileWriter("d:/io/test.txt"))){
//修改集合中的王五的性别
for (Student student : students) {
String name = student.getName();
if ("王五".equals(name)){
student.setSex("男");
}
writer.write(student.toLine());
writer.newLine();
}
writer.flush();
}catch (IOException e) {
e.printStackTrace();
}
}
}
以上代码是一个使用缓冲字符流
BufferedReader和BufferedWriter的示例。首先,在
main()方法中,我们创建了一个空的Student对象列表students,用于存储从文件中读取的学生信息。然后,我们使用
BufferedReader和FileReader创建了一个读取文件的流reader,并将其传入BufferedReader的构造方法中进行包装。接下来,我们使用
readLine()方法从输入流中逐行读取数据。每读取一行数据,我们将其根据逗号分隔成一个字符串数组arr,然后根据数组中的元素构建一个Student对象,并将其添加到students列表中。在读取完文件内容后,我们关闭了
reader流。接下来,我们使用
BufferedWriter和FileWriter创建了一个写入文件的流writer,并将其传入BufferedWriter的构造方法中进行包装。然后,我们遍历
students列表中的每个Student对象。如果学生的名字是 "王五",则将其性别修改为 "男"。然后,我们使用
write()方法将学生对象转换为一行字符串,并使用newLine()方法插入换行符。最后,我们调用flush()方法将缓冲区的内容写入文件,并关闭writer流。这样就完成了将文件中的性别修正为 "男" 的操作。
请注意,在读取文件和写入文件时,我们都使用了缓冲字符流
BufferedReader和BufferedWriter,以提高读写的效率。同时,在使用这些流时,我们使用了try-with-resources语句,以确保流被正确关闭。
文章详细介绍了Java中的File类如何用于文件和目录的基本操作,如检查文件存在、获取文件属性、删除文件夹等。接着,文章讨论了Java的I/O流,包括字节流和字符流的使用,如OutputStream和InputStream用于文件的读写,以及如何利用流进行文件复制。还提到了字符流的BufferedReader和BufferedWriter,用于提高读写效率,并展示了如何通过缓冲流修改文件内容。
1201

被折叠的 条评论
为什么被折叠?



