文章目录
- 1. 文件路径
-
- 绝对路径
- 相对路径
- 2. Java中操作文件
-
- 2.1 File 的常用属性,方法和构造方法
-
- 属性
- 构造方法
- 方法
- 使用示例1: get相关方法的使用
- 使用示例2: 普通文件的创建和删除
- 使用示例3: deleteOnExit 的使用
- 使用示例4: 单级目录的创建
- 使用示例5: 多级目录的创建
- 使用示例6: 文件的重命名
- 使用示例7: 文件的移动
- 使用示例8: 打印当前目录下所有的文件名
- 2.2 面试题(遍历一个目录下所有的文件,包含子目录的文件)
- 3. 文件内容的读写 -- 数据流
-
- 3.1 InputStream --- --- 读
-
- 方法
- FileInputStream 的构造方法
- 使用示例1: 一次读写一个字符
- 使用示例2: 一次读多个字符
- 使用示例3: 当文件中的内容是中文时
- 使用示例4: 使用Scanner进行字符读取
- 3.2 OutputStream --- --- 写
-
- 方法
- 使用示例1: 一次写入一个字符
- 使用示例2: 一次写入多个字符
- 使用示例3: 使String来辅助写入字符
- 使用示例4: 利用 PrintWriter 类来辅助写入字符
- 4. 实现一些案例
-
- 案例1:
- 案例2:
- 案例3:
1. 文件路径
文章图片
绝对路径 绝对路径 (absolute path) : 以一个盘符开头的路径,就是绝对路径
例如这里的相对路径 相对路径 (relative path) 一般是以D:\java\IntelliJ IDEA Community Edition 2021.2.2\bin\idea64.exe
就是绝对路径
.
或者..
开头的路径.一般会有一个基准,去找对应的路径..
就是当前目录 ..
当前目录的上一目录例如2. Java中操作文件 Java 中通过
- 以
D:\java\IntelliJ IDEA Community Edition 2021.2.2\bin
作为基准 相对路径可以写成.\idea64.exe
- 以
D:\java\IntelliJ IDEA Community Edition 2021.2.2
作为基准 相对路径可写成.\bin\idea64.exe
- 以
D:\java\IntelliJ IDEA Community Edition 2021.2.2\bin\idea64.exe
作为基准 相对路径可用写成..\idea64.exe
java.io.File
类来对一个文件(包括目录)进行抽象的描述。2.1 File 的常用属性,方法和构造方法 属性
修饰符及类型 | 属性 | 说明 |
---|---|---|
static String | pathSeparator | 依赖于系统的路径分隔符,String 类型的表示 |
static char | pathSeparator | 依赖于系统的路径分隔符,char 类型的表示 |
签名 | 说明 |
---|---|
File(File parent, String child) | 根据父目录 + 孩子文件路径,创建一个新的 File 实例 |
File(String pathname) | 根据文件路径创建一个新的 File 实例,路径可以是绝对路径或者相对路径 |
File(String parent, String child) | 根据父目录 + 孩子文件路径,创建一个新的 File 实例,父目录用路径表示 |
方法签名 | 说明 |
---|---|
String getParent() | 返回 File 对象的父目录文件路径 |
String getName() | 返回 FIle 对象的纯文件名称 |
String getPath() | 返回 File 对象的文件路径 |
String getAbsolutePath() | 返回 File 对象的绝对路径 |
String getCanonicalPath() | 返回 File 对象的修饰过的绝对路径 |
boolean exists() | 判断 File 对象描述的文件是否真实存在 |
boolean isDirectory() | 判断 File 对象代表的文件是否是一个目录 |
boolean isFile() | 判断 File 对象代表的文件是否是一个普通文件 |
boolean createNewFile() | 根据 File 对象,自动创建一个空文件。成功创建后返回 true |
boolean delete() | 根据 File 对象,删除该文件。成功删除后返回 true |
void deleteOnExit() | 根据 File 对象,标注文件将被删除,删除动作会到JVM 运行结束时才会进行 |
String[] list() | 返回 File 对象代表的目录下的所有文件名 |
File[] listFiles() | 返回 File 对象代表的目录下的所有文件,以 File 对象表示 |
boolean mkdir() | 创建 File 对象代表的目录 |
boolean mkdirs() | 创建 File 对象代表的目录,如果必要,会创建中间目录 |
boolean renameTo(File dest) | 进行文件改名,也可以视为我们平时的剪切、粘贴操作 |
boolean canRead() | 判断用户是否对文件有可读权限 |
boolean canWrite() | 判断用户是否对文件有可写权限 |
使用示例1: get相关方法的使用
import java.io.File;
import java.io.IOException;
public class FileDemo1 {
public static void main(String[] args) throws IOException {
File file = new File("./test.txt");
//这里的test.txt不一定存在
System.out.println(file.getParent());
System.out.println(file.getName());
System.out.println(file.getPath());
System.out.println(file.getAbsolutePath());
System.out.println(file.getCanonicalPath());
}
}
运行结果截图:
文章图片
使用示例2: 普通文件的创建和删除
import java.io.File;
import java.io.IOException;
public class FileDemo2 {
public static void main(String[] args) throws IOException {
File file = new File("./test.txt");
System.out.println("创建前:");
System.out.println("文件是否真实存在: "+file.exists());
System.out.println("文件是否是一个目录: "+file.isDirectory());
System.out.println("文件是否是一个普通文件: "+file.isFile());
System.out.println("创建后:");
System.out.println("文件创建是否成功: "+file.createNewFile());
System.out.println("文件是否真实存在: "+file.exists());
System.out.println("文件是否是一个目录: "+file.isDirectory());
System.out.println("文件是否是一个普通文件: "+file.isFile());
System.out.println("再次创建:");
System.out.println("文件创建是否成功: "+file.createNewFile());
}
}
运行结果截图:
文章图片
使用示例3: deleteOnExit 的使用
import java.io.File;
import java.io.IOException;
public class FileDemo3 {
public static void main(String[] args) throws IOException, InterruptedException {
File file = new File("./test.txt");
System.out.println(file.exists());
System.out.println(file.createNewFile());
System.out.println(file.exists());
Thread.sleep(3000);
file.deleteOnExit();
System.out.println(file.exists());
}
}
代码截图:
发现运行过程中,三秒之后,输出文件存在之后,文件被删除
文章图片
使用示例4: 单级目录的创建
import java.io.File;
public class FileDemo4 {
public static void main(String[] args) {
File file = new File("test");
System.out.println(file.isDirectory());
System.out.println(file.isFile());
System.out.println(file.mkdir());
System.out.println(file.isDirectory());
System.out.println(file.isFile());
}
}
运行截图:
文章图片
使用示例5: 多级目录的创建
import java.io.File;
public class FileDemo5 {
public static void main(String[] args) {
File file = new File("aaa/bbb/ccc");
System.out.println(file.isDirectory());
System.out.println(file.isFile());
System.out.println(file.mkdirs());
System.out.println(file.isDirectory());
System.out.println(file.isFile());
}
}
运行截图:
文章图片
使用示例6: 文件的重命名
import java.io.File;
import java.io.IOException;
public class FileDemo6 {
public static void main(String[] args) throws IOException {
File file1 = new File("./test.txt");
File file2 = new File("./test2.txt");
System.out.println(file1.exists());
System.out.println(file1.createNewFile());
System.out.println(file1.exists());
System.out.println(file1.renameTo(file2));
}
}
运行截图:
文章图片
使用示例7: 文件的移动
import java.io.File;
public class FileDemo7 {
public static void main(String[] args) {
File file1 = new File("./test2.txt");
File file2 = new File("./aaa/test2.txt");
file1.renameTo(file2);
}
}
运行截图:
文章图片
使用示例8: 打印当前目录下所有的文件名
import java.io.File;
import java.util.Arrays;
public class FileDemo8 {
public static void main(String[] args) {
File file = new File(".");
String[] files = file.list();
System.out.println(Arrays.toString(files));
}
}
运行截图:
文章图片
2.2 面试题(遍历一个目录下所有的文件,包含子目录的文件)
import java.io.File;
import java.util.ArrayList;
import java.util.List;
public class FileDemo9 {
// 这里的result 用来记录每一个目录里面的路径
public static List result = new ArrayList<>();
public static void getAllFiles(String basePath){
File file = new File(basePath);
if(file.isFile()){
//如果是一个文件就之间add
result.add(basePath);
return ;
}else if (file.isDirectory()){
//这里是一个目录 就需要递归
String[] files = file.list();
for (String f : files){
getAllFiles(basePath+"/"+f);
}
}else{
//非普通文件,暂不考虑
}
}public static void main(String[] args) {
getAllFiles(".");
for (String s : result){
System.out.println(s);
}
}
}
运行结果:
文章图片
3. 文件内容的读写 – 数据流 3.1 InputStream — — 读 方法
方法 | 说明 |
---|---|
int read() | 读取一个字节的数据,返回 -1 代表已经完全读完了 |
int read(byte[] b) | 最多读取 b.length 字节的数据到 b 中,返回实际读到的数量;-1 代表以及读完了 |
int read(byte[] b,int off, int len) | 最多读取 len - off 字节的数据到 b 中,放在从 off 开始,返回实际读到的数量;-1 代表以及读完了 |
void close() | 关闭字节流 |
InputStream
是一个抽象类.可用使用FileInputStream
来实现.FileInputStream 的构造方法
构造方法 | 说明 |
---|---|
FileInputStream(File file) | 利用 File 构造文件输入流 |
FileInputStream(String name) | 利用文件路径构造文件输入流 |
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
public class FileDemo10 {
public static void main(String[] args) throws IOException {
try(InputStream inputStream = new FileInputStream("test.txt")){
while (true){
int b = inputStream.read();
if(b == -1){
break;
}
System.out.printf("%c",b);
}
}
}
}
运行结果:
文章图片
使用示例2: 一次读多个字符
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
public class FileDemo11 {
public static void main(String[] args) throws IOException {
try (InputStream inputStream = new FileInputStream("test.txt")){
byte[] bytes = new byte[1024];
while(true) {
int len = inputStream.read(bytes);
if(len == -1){
break;
}
for (int i = 0;
i < len;
i++) {
System.out.printf("%c",bytes[i]);
}
}
}
}
}
文章图片
注: 示例2比示例1更好,因为IO次数少,性能也就更好
使用示例3: 当文件中的内容是中文时
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
public class FileDemo12 {
public static void main(String[] args) throws IOException {
try (InputStream inputStream = new FileInputStream("test.txt")){
byte[] bytes = new byte[1024];
while (true){
int len = inputStream.read(bytes);
if(len == -1){
break;
}
// 中文是占3个字节的
for (int i = 0;
i < len;
i+=3) {
String s = new String(bytes,i,3,"UTF-8");
System.out.printf("%s",s);
}
}
}
}
}
文章图片
注: 这里只是适用于全是中文的情况,这个只是了解,并不适用
使用示例4: 使用Scanner进行字符读取
构造方法 | 说明 |
---|---|
Scanner(InputStream is, String charset) | 使用 charset 字符集进行 is 的扫描读取 |
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Scanner;
public class FileDemo13 {
public static void main(String[] args) throws IOException {
try (InputStream inputStream = new FileInputStream("test.txt")){
Scanner scanner = new Scanner(inputStream,"UTF-8");
while (scanner.hasNext()){
String s = scanner.nextLine();
System.out.print(s);
}
}
}
}
3.2 OutputStream — — 写 方法
方法 | 说明 |
---|---|
void write(int b) | 写入要给字节的数据 |
void write(byte[] b) | 将 b 这个字符数组中的数据全部写入 os 中 |
int write(byte[] b, int off,int len) | 将 b 这个字符数组中从 off 开始的数据写入 os 中,一共写 len 个 |
void close() | 关闭字节流 |
void flush() | 重要:我们知道 I/O 的速度是很慢的,所以,大多的 OutputStream 为了减少设备操作的次数,在写数据的时候都会将数据先暂时写入内存的一个指定区域里,直到该区域满了或者其他指定条件时才真正将数据写入设备中,这个区域一般称为缓冲区。但造成一个结果,就是我们写的数据,很可能会遗留一部分在缓冲区中。需要在最后或者合适的位置,调用 flush(刷新)操作,将数据刷到设备中。 |
OutputStream
也是一个抽象类,可以使用FileOutputStream
来实现使用示例1: 一次写入一个字符
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
public class FileDemo14 {
public static void main(String[] args) throws IOException {
try (OutputStream outputStream = new FileOutputStream("test.txt")){
outputStream.write('h');
outputStream.write('e');
outputStream.write('l');
outputStream.write('l');
outputStream.write('o');
outputStream.flush();
}
}
}
文章图片
使用示例2: 一次写入多个字符
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
public class FileDemo15 {
public static void main(String[] args) throws IOException {
try(OutputStream outputStream = new FileOutputStream("test.txt")){
byte[] bytes = new byte[]{
(byte) 'h',(byte) 'e',(byte) 'y'
};
outputStream.write(bytes);
outputStream.flush();
}
}
}
文章图片
使用示例3: 使String来辅助写入字符
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
public class FileDemo15 {
public static void main(String[] args) throws IOException {
try(OutputStream outputStream = new FileOutputStream("test.txt")){
String str = "hello world";
outputStream.write(str.getBytes());
outputStream.flush();
}
}
}
文章图片
使用示例4: 利用 PrintWriter 类来辅助写入字符
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
public class FileDemo16 {
public static void main(String[] args) throws IOException {
try(OutputStream outputStream = new FileOutputStream("test.txt")){
try(PrintWriter writer = new PrintWriter(outputStream)){
writer.println("hello 你好");
}
}
}
}
文章图片
4. 实现一些案例 案例1:
扫描一个指定的目录,并找到名称中包含指定字符的所有普通文件,并且根据用户的选择来判断是否要删除文件.
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Delete {
public static void main(String[] args) throws IOException {
// 1. 用户输入路径
Scanner sc = new Scanner(System.in);
System.out.print("请输入需要扫描的根路径: ");
String rootDirPath = sc.nextLine();
// 2. 如果输入的根目录不存在,之间返回
File file = new File(rootDirPath);
if(!file.isDirectory()){
System.out.println("您输入的目录错误!退出程序!");
return;
}
// 3. 用户输入需要查找的文件名中的内容
System.out.print("请输入要查找的文件名中含有的字符: ");
String name = sc.nextLine();
// 4. 递归遍历目录,并把满足条件的路径存入 result 中
List result = new ArrayList<>();
scanDir(file,name,result);
// 5. 打印result中的内容 由用户决定是否删除
if(result.size() == 0) {
System.out.println("没有要找的文件!");
return;
}
for(File f : result){
System.out.println(f.getCanonicalFile());
System.out.println("请问是否删除这个文件(Y/N)");
String decision = sc.nextLine();
if(decision.equals("Y")){
f.delete();
System.out.println("删除成功!");
return;
}
}
}private static void scanDir(File file, String name, List result) {
File[] files = file.listFiles();
// 判断一下 files 是不是空或者files是不是没有东西
if (files == null || files.length == 0) {
//空目录
return;
}for(File f:files){
if(f.isDirectory()){
//是目录就进行查找
scanDir(f,name,result);
}else{
// 不是目录就判断名字是否带有需要查找的关键字 使用contains方法
if(f.getName().contains(name)){
result.add(f.getAbsoluteFile());
}
}
}
}}
文章图片
案例2:
进行普通文件的复制
import java.io.*;
import java.util.Scanner;
public class Copy {
public static void main(String[] args) throws IOException {
// 1. 让用户输入要复制的文件路径
Scanner sc = new Scanner(System.in);
System.out.print("请输入要复制文件的路径: ");
String srcPath = sc.nextLine();
File srcFile = new File(srcPath);
// 2. 判断输入的是否是文件,不是就返回
if(!srcFile.isFile()){
System.out.println("输入的文件路径错误!程序结束!");
return;
}
// 3. 是文件 就输入要复制到的路径
System.out.print("请输入要复制到的目标路径: ");
String destPath = sc.nextLine();
File destFile = new File(destPath);
// 4. 判断是否存在复制后的文件,如果有就返回复制失败
if(destFile.exists()){
System.out.println("该目录已有该文件,复制失败!");
return;
}
// 5. 判断父级目录存不存在 不存在就创建目录
if(!destFile.getParentFile().exists()){
destFile.getParentFile().mkdirs();
}
// 6. 复制文件
try (InputStream inputStream = new FileInputStream(srcFile);
OutputStream outputStream = new FileOutputStream(destFile)) {
while(true) {
byte[] bytes = new byte[1024];
int len = inputStream.read(bytes);
if(len == -1){
break;
}
outputStream.write(bytes,0,len);
}
outputStream.flush();
}
System.out.println("复制完成!!!");
}
}
文章图片
文章图片
案例3:
扫描指定目录,并找到名称或者内容中包含指定字符的所有普通文件(不包含目录)
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Search {
public static void main(String[] args) throws IOException {
// 1. 用户输入要扫描的目录路径
Scanner sc = new Scanner(System.in);
System.out.print("请输入要查找的文件的目录的路径: ");
String searchPath = sc.nextLine();
File file = new File(searchPath);
// 2. 判断是否存在目录
if(!file.isDirectory()) {
System.out.println("输入的目录路径错误!程序结束!");
return;
}
// 3. 用户输入要查找的内容
System.out.print("请输入你要查找的内容: ");
String str = sc.nextLine();
List result = new ArrayList<>();
// 4. 用递归的方式遍历 符合的存入result
scanResult(file,str,result);
// 5. 遍历结果
System.out.println("找到了"+result.size()+"个符合条件的内容");
for(File file1 : result){
System.out.println(file1.getCanonicalFile());
}
}
public static void scanResult (File file,String str,List result) throws IOException {
// files里都是目录
File[] files = file.listFiles();
// files为空或者长度为0就是没有内容 直接返回
if(files == null || files.length == 0){
return;
}
// 遍历
for(File f : files){
// 是目录就递归
if(f.isDirectory()){
scanResult(f,str,result);
}else{
// 不是目录就判断是否准则符合要求的内容
if(isContains(f,str)){
result.add(f);
}
}
}
}
public static boolean isContains(File f,String s) throws IOException{
StringBuilder sb = new StringBuilder();
try(InputStream inputStream = new FileInputStream(f)){
try(Scanner sc = new Scanner(inputStream,"UTF-8")){
// 读取数据
// 每一行的读
// 并添加到sb中
while (sc.hasNextLine()){
String str = sc.nextLine();
sb.append(str+"/n");
}
}
}
// 如果和-1相等就是没有要找的内容
return sb.indexOf(s) == -1;
}
}
【操作系统|操作系统 --- 文件操作和IO】
文章图片
推荐阅读
- MySQL数据库|MySQL数据库 --- 事务面试重点
- 操作系统|操作系统 ---多线程(进阶)
- 《Linux运维实战总结》|《Linux运维实战(shell脚本解析yaml文件变量》)
- Linux全解析|Shell全解析(一)(Shell脚本)
- 聊聊mysql的树形结构存储及查询
- SpringMVC 解析(四)编程式路由
- 蓝桥杯题解|蓝桥杯“字串排序“题解
- source insight4.0最常用到的设置
- 软件开发架构演变过程