File类的用法

news2024/9/22 21:20:40

目录

File的常见方法

 普通文件的创建

 普通文件的删除

deleteOnExit

目录的创建 

mkdir

mkdirs

文件的重命名和剪切

剪切

 重命名

InputStream

read()

OutputStream

write()

Reader

Writer

write(String str)

代码练习

扫描指定⽬录,并找到名称中包含指定字符的所有普通⽂件(不包含⽬录),并且后续询问⽤⼾是否 要删除该⽂件

进⾏普通⽂件的复制

扫描指定⽬录,并找到名称或者内容中包含指定字符的所有普通⽂件(不包含⽬录)


File是Java中的一个重要类,位于java.io包中,可以用来创建、删除、查询文件或目录等

什么是文件(File)?

文件可以是文本、图像、视频、音频、程序代码等多种类型的数据

什么是目录(Directory)?

通俗点来说,目录就是文件夹,用于将多个文件存放在一起,便于管理

什么是绝对路径,什么是相对路径,什么是工作路径?

绝对路径就是从根目录开始的,绝对路径不受当前工作路径的影响,而相对路径就是从当前目录开始,System.getProperty("user.dir") 这种方式来获取当前的工作路径

public static void main(String[] args) throws IOException {
        File file = new File("test1.txt");
        System.out.println(file.getName());//文件或目录最后一个路径元素
        System.out.println(file.getPath());//返回文件的路径
        System.out.println(file.getAbsoluteFile());//返回文件的绝对路径
        System.out.println(file.getCanonicalFile());//返回文件规范的绝对路径
    }

运行结果:

File的常见方法

返回值方法名说明
StringgetParent()返回 File 对象的⽗⽬录⽂件路径
StringgetName()返回文件或目录的最后一个名称
StringgetPath()返回 File 对象的⽂件路径
StringgetAbsolutePath()返回 File 对象的绝对路径
StringgetCanonicalPath()返回文件的规范绝对路径
booleanexists()判断 File 对象描述的⽂件是否存在
booleanisDirectory()判断 File 对象代表的⽂件是否是⼀个⽬录
booleanisFile()判断 File 对象代表的⽂件是否是⼀个普通⽂件
booleancreateNewFile()根据 File 对象,⾃动创建⼀个空⽂件,成功创建后返回 true
booleandelete()根据 File 对象,删除该⽂件。成功 删除后返回 true
voiddeleteOnExit()

根据 File 对象,标注⽂件将被删除,

删除动作会到 JVM 运⾏结束时才会进⾏

String[]list()返回目录中的每个文件和目录的名称(不包括路径)
File[]listFiles()返回目录中所有文件和子目录的File对象(包括路径)
booleanmkdir()创建单个目录,父目录必须存在
booleanmkdirs()

创建多级目录,父目录不存在则会自动创建父目录

booleanrenameTo(File dest)进⾏⽂件改名,也可以视为我们平时的剪切、粘贴操作
booleancanRead()判断⽤⼾是否对⽂件有可读权限
booleancanWrite()判断⽤⼾是否对⽂件有可写权限

 普通文件的创建

public static void main(String[] args) throws IOException {
        File file = new File("D:\\java");
        System.out.println(file.exists());//true
        System.out.println(file.isDirectory());//true,因为‘java’为目录
        System.out.println(file.isFile());//false
        System.out.println(file.createNewFile());//false,因为‘java’是个文件夹如果
        //再次创建的话会返回false,如果改成其他名字就可以创建成功


    }

 普通文件的删除

public static void main(String[] args) throws IOException {
        File file = new File("D:\\java\\test1.txt");
        System.out.println(file.exists());//返回false,因为test1.txt并没有在’java‘这个路径上
        System.out.println(file.createNewFile());//返回true,并成功创建出test1.txt这个文本文件
        System.out.println(file.exists());//返回true,因为成功创建出了test1.txt,所以可以找到
        System.out.println(file.delete());//返回true,因为存在所以可以删除,如果不存在则删除失败返回false
        System.out.println(file.exists());//返回false,因为成功删除,所以在当前路径下找不到test1.txt
    }

deleteOnExit

我们可以将这个理解成延迟删除,意思是只有当程序运行结束的时候才会删除

public static void main(String[] args) {
        File file = new File("D:\\java\\test.txt");
        file.deleteOnExit();
        Scanner scanner = new Scanner(System.in);
        System.out.println("请随便输入");
        scanner.next();//输入,用来观察是否被删除
        System.out.println("删除成功");
    }

 通过下面这张图可以观察到当程序还未结束的时候,这个文件是没有被删除的,但是当我输入完并按下回车之后,这个文件就会立刻被删掉

 

目录的创建 

mkdir

public static void main(String[] args) {
        File file = new File("D:\\java\\newFile1");
        System.out.println(file.isDirectory());//用来判断是否为目录,如果是返回true,如果不是返回false
        System.out.println(file.mkdir());//创建成功,因为‘java’这个目录存在
        //如果‘java’这个目录不存在则创建失败,那么就使用mkdirs
    }

mkdirs

mkdirs与mkdir不同的是,对于mkdirs来说如果父目录,也就是中间目录不存在的话则会自动创建父目录,而后者不会

public static void main(String[] args) {
        File file = new File("D:\\java\\newFile2\\newFile3");
        System.out.println(file.mkdirs());//在‘java’这个目录下创建一个newFile2目录
        //并在newFile2这个目录下创建newFile3,因为newFile2这个目录不存在,但是我们使用的是
        //mkdirs所以会自动帮我们创建好newFile2这个目录
    }

文件的重命名和剪切

剪切

public static void main(String[] args) {
        File src = new File("D:\\java\\test1.txt");
        File dest = new File("D:\\java\\File1\\test2.txt");
        System.out.println(src.exists());
        System.out.println(dest.exists());
        System.out.println(src.renameTo(dest));
    }

没执行前

java文件中保存着test1.txt 和 test2.txt 这两个文本文件,并且File1 目录里面为空

 

程序执行后 

将D:\java\test1.txt 移动到 D:\java\File1\ 目录并重命名为 test2.txt

 

 重命名

public static void main(String[] args) {
        File src = new File("D:\\java\\test1.txt");
        File dest = new File("D:\\java\\test3.txt");
        System.out.println(src.exists());
        System.out.println(dest.exists());//要求test3不存在
        System.out.println(src.renameTo(dest));
    }

运行结果

只有当目标文件不存在的时候才能完成重命名操作,所以上述代码成功将 test1.txt 重命名为 test3.txt   

InputStream

返回值方法名作用
intread()读取⼀个字节的数据,返回 -1 代表 已经完全读完了
intread(byte[] b)

最多读取 b.length 字节的数据到 b 中,返回实际读到的数量

;-1 代表 以及读完了

intread(byte[] b, int off, int len)

最多读取 len - off 字节的数据到 b 中,放在从 off 开始,

返回实际读 到的数量;-1 代表以及读完了

voidclose()关闭字节流

InputStream 只是⼀个抽象类,要使⽤还需要具体的实现类。

read()

代码1

public static void main(String[] args) throws IOException {
        InputStream inputStream = new FileInputStream("D:\\java\\test.txt");
        while(true){
            int b = inputStream.read();
            if(b == -1){
                break;
            }
            System.out.printf("%c",b);
        }
        inputStream.close();
    }

代码2 

public static void main(String[] args) throws IOException {
        InputStream inputStream = new FileInputStream("D:\\java\\test.txt");
        while(true){
            byte[] buffer = new byte[1024];
            int len = inputStream.read(buffer);
            if(len == -1) break;
            for(int i = 0;i<len;i++){
                System.out.printf("%c",buffer[i]);
            }
        }
    }

代码2相对于代码1来说减少了大量的 IO 操作,因为 read() 方法是一次读一个字节,而代码2就是利用这一点将读取到的数据放到 buffer 里面,直到读满1024个字节或者内容读取完毕才会执行打印,这样就减少了大量的 IO 操作

运行结果就是看你的 test.txt 里面的内容是什么,但是不推荐内容包含中文,如果需要使用 

FileInputStream 来查看有包含中文内容的请继续往下看

使用 FileInputStream 来读取中文

public static void main(String[] args) throws IOException {
        InputStream inputStream = new FileInputStream("D:\\java\\test.txt");
        byte[] buffer = new byte[1024];
        while(true){
            int len = inputStream.read(buffer);
            if(len == -1) break;
            for(int i = 0;i<len;i+=3){
                String s = new String(buffer,i,3,"UTF-8");
                System.out.printf("%s",s);
            }
        }
        inputStream.close();
    }

但是这样写就会有一个弊端,就是文本中必须全部都是中文,因为对于UTF8来说,每个汉字都会被分割成3个字节

OutputStream

返回值方法名说明
voidwrite(int b)写⼊要给字节的数据,一次只能写入一个字节
voidwrite(byte[] b)

将 b 这个字符数组中的数据全部写 ⼊ os 中

一次可以写入多个字节

intwrite(byte[] b, int off, int len)读取 b 这个字符数组从 [off,off+len) 的长度
voidclose()关闭字节流
voidflush()我们知道 I/O 的速度是很慢 的,所以,⼤多的 OutputStream 为了减少设备操作的次数,在写数 据的时候都会将数据先暂时写⼊内 存的⼀个指定区域⾥,直到该区域 满了或者其他指定条件时才真正将 数据写⼊设备中,这个区域⼀般称 为缓冲区。但造成⼀个结果,就是 我们写的数据,很可能会遗留⼀部 分在缓冲区中。需要在最后或者合 适的位置,调⽤ flush(刷新)操 作,将数据刷到设备中。

write()

在代码中,如果我们使用try-with-resources语句,则不用手动进行字符/字节流的关闭,因为如果在try代码块结束的时候就会自动调用 close ,而不需要手动进行,用来放在忘记关闭而导致的内存泄漏问题

public static void main(String[] args) {
        try(OutputStream os = new FileOutputStream("D:\\test.txt")){
            os.write('H');
            os.write('E');
            os.write('L');
            os.write('L');
            os.write('O');
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

但是使用上述代码我们可以看到,如果我们再进行一次写操作,之前的内容就会消失不见,这是因为只要我们使用OutputStream 打开文件,里面的内容就会消失,如何解决这个问题也很简单,因为OutputStream 默认是会清空之前的内容的,但是我们还有一个追加操作,就是在路径后面写一个“ true” 参数

OutputStream os = new FileOutputStream("D:\\java\\test.txt",true)

我们也可以用 write(byte[] b)方法进行写入,方式如下

public static void main(String[] args) {
        try(OutputStream os = new FileOutputStream("D:\\java\\test.txt",true)){
            byte[] b = new byte[]{'a','b','c','d'};
            os.write(b);
        } catch (IOException e){
            e.printStackTrace();
        }
    }

但是当我们使用InputStream 和 OutputStream 的时候读取和写入中文就比较麻烦,所以我们可以使用更简单的方法来进行中文的输入和输出,请看下文


Reader

public static void main(String[] args) {
        try(Reader reader = new FileReader("D:\\java\\test.txt")){
            while(true){
                int n = reader.read();
                if(n == -1){
                    return;
                }
                char ch = (char)n;
                System.out.print(ch+" ");
            }
        } catch (IOException e){
            e.printStackTrace();
        }
    }

对于这段代码来说,不管你的内容是中文还是英文还是中英混杂都可以正确的读取出来

输出结果:

 

看到这里可能就会有一个疑问?明明 java 中的 char 类型表示的是 2 个字节,但是 java 中的汉字是使用 utf8 来表示的,一个汉字 3 个字节,为什么可以使用 char 来表示 3个字节的汉字呢?其实

java 的 char 在表示汉字的时候并不是用 utf8 而是使用 unicode 的编码方式,在 unicode 中一个汉字就表示 2 个字节 

在这里我也推荐一个很好用的查看字符编码的网站

查看字符编码(UTF-8)icon-default.png?t=N7T8http://www.mytju.com/classCode/tools/encode_utf8.asp

Writer

write(String str)

这个方法可以直接写入字符串,非常方便,如果要进行追加操作也一样在后面加个true就可以

public static void main(String[] args) {
        try(Writer writer = new FileWriter("D:\\java\\test.txt",true)){
            writer.write("你好中国");
        } catch (IOException e){
            e.printStackTrace();
        }
    }

其他方法其实和前面介绍的都差不多,这里就不再重复了

代码练习

扫描指定⽬录,并找到名称中包含指定字符的所有普通⽂件(不包含⽬录),并且后续询问⽤⼾是否 要删除该⽂件

package FileTest;

import java.io.File;
import java.util.Scanner;

public class demo15 {

    private static void scan(File currentFile,String key){
        if(!currentFile.isDirectory()){
            return;
        }
        File[] files = currentFile.listFiles();
        if(files.length == 0 || files == null){
            return;
        }
        for(File f : files){
            if(f.isFile()){
                FileDelete(f,key);
            } else {
                scan(f,key);
            }
        }
    }

    private static void FileDelete(File f,String key){
        if(!f.getName().contains(key)){
            //文件名中不包含指定的关键字
            return;
        }
        Scanner scanner = new Scanner(System.in);
        System.out.println(f.getAbsoluteFile()+"是否要删除Y/y");
        String choice = scanner.next();
        if(choice.equals("y") || choice.equals("Y")){
            f.delete();
        }
    }

    public static void main(String[] args) {
        System.out.println("请输入要搜索的路径");
        Scanner scanner = new Scanner(System.in);
        String rootPath = scanner.next();
        File rootFile = new File(rootPath);
        if(!rootFile.isDirectory()){
            System.out.println("输入的路径不存在");
            return;
        }
        //走到此处就说明路径存在
        System.out.println("请输入要删除的文件名字的关键字");
        String key = scanner.next();

        //利用递归进行查找
        scan(rootFile,key);
    }
}

进⾏普通⽂件的复制

如果文件在目录中不存在,就会自动创建,但是如果连目录都不存在那就不行了

package FileTest;

import java.io.*;
import java.util.Scanner;

public class demo17 {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入源文件的路径");
        String srcPath = scanner.next();
        File srcFile = new File(srcPath);
        if(!srcFile.isFile()){
            System.out.println("源文件路径有误");
            return;
        }

        System.out.println("请输入目标文件的路径");
        String destPath = scanner.next();
        File destFile = new File(destPath);
        //注意: 这里目标文件可以不存在但是父目录必须存在
        if(!destFile.getParentFile().isDirectory()){
            System.out.println("目标文件路径有误");
            return;
        }

        //执行复制的过程
        try(InputStream inputStream = new FileInputStream(srcFile);
            OutputStream outputStream = new FileOutputStream(destFile)){

            while(true){
                byte[] buffer = new byte[1024];
                int n = inputStream.read(buffer);//返回读到的字节数量
                if(n == -1){
                    return;
                }
                outputStream.write(buffer,0,n);//读取0~n个,因为buffer可能装不满
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

代码执行前:

 

代码执行后:

 

执行过程:

D:\java\test.txt  的意思就是将 test.txt 复制到D:\java\File1 这个路径里面并重命名为 newtest.txt

这里的File1这个父目录必须存在,这段代码不仅可以复制文件还可以复制图片等

扫描指定⽬录,并找到名称或者内容中包含指定字符的所有普通⽂件(不包含⽬录)

package FileTest;

import java.io.*;
import java.util.Scanner;

public class demo18 {
    public static void main(String[] args) {
        System.out.println("请输入要搜索的路径");
        Scanner scanner = new Scanner(System.in);
        String rootPath = scanner.next();
        File rootFile = new File(rootPath);
        if(!rootFile.isDirectory()){
            System.out.println("路径不存在");
            return;
        }
        System.out.println("请输入要找的关键字");
        String key = scanner.next();
        scan(rootFile,key);

    }

    private static void scan(File rootFile, String key) {
        if(!rootFile.isDirectory()){
            return;
        }
        File[] files = rootFile.listFiles();
        if(files.length == 0 || files == null){
            return;
        }
        for(File f : files){
            if(f.isFile()){
                search(f,key);
            } else {
                scan(f,key);
            }
        }
    }

    private static void search(File f, String key) {
        StringBuilder sb = new StringBuilder();
        try(Reader reader = new FileReader(f)){
            char[] buffer = new char[1024];
            while(true){
                int n = reader.read(buffer);
                if(n == -1){
                    break;
                }
                String s = new String(buffer,0,n);//将每个字符拼接成字符串
                sb.append(s);//将读到的字符串拼接到一起最后判断
            }
        } catch (IOException e){
            e.printStackTrace();
        }

        if(sb.indexOf(key) == -1){
            //没有找到
            return;
        }
        System.out.println("找到匹配的文件: "+f.getAbsolutePath());
    }

}

上述代码只要文件中包含了关键字的都能被找的,但是这个并不能适用太复杂的目录或者文件太大的情况

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1976830.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

git clone private repo

Create personal access token Clone repo $ git clone https://<user_name>:<personal_access_tokens>github.com/<user_name>/<repo_name>.git

【DOCKER】VNC可视化UBUNTU容器

1. 启动测试容器 # 启动容器 # -e USERu20 vncserver所需环境变量 # -p 15901:5901 vncserver所需端口 docker run -id --privilegedtrue --restart always --useru20 --workdir/home/u20 -p 15901:5901 -e USERu20 --name ui u20:dev# 进入容器 docker exec -it ui /bin/ba…

jupyter支持跨机器远程访问

1. 远程访问场景 本地往往缺少GPU设备&#xff0c;为了让我们的代码能在有GPU设备的机器上运行&#xff0c;就需要在远程机器上启动jupyter notebook, 这意味着我们要在本地机器的浏览器上访问远程机器上的jupyter notebook。但是直接按ip访问会报如下错误&#xff1a; 因为ju…

MATLAB优化模型(3)

一、前言 在MATLAB中处理各种优化问题&#xff0c;如背包问题、指派问题&#xff08;也称为分配问题&#xff09;、抽屉原理应用、旅行商问题&#xff08;TSP&#xff09;以及排队论模型&#xff0c;通常需要结合MATLAB的优化工具箱&#xff08;如Optimization Toolbox&#xf…

C++ | 动态内存管理 new、delete (用法、底层)详解

目录 简单回顾C语言动态内存管理 new、delete的用法 内置类型 new delete 自定义类型 new、delete底层讲解&#xff08;重要&#xff09; operator new 与 operator delete 定位 new 结语 简单回顾C语言动态内存管理 在C语言的学习阶段 我们接触到了三个能在堆上开辟…

vulhub靶场之wordpress关卡(保姆级教程)

一.打开wordpress关卡 1.选择简体中文 然后添加信息 点击安装wordpress 1.2 登陆后台 1.3 在后台修改模板 1.4 找一个php文件&#xff0c;在最开头加入一句话木马 点击更新 然后访问默认模板路径 下面的是默认的模板路径 /wp-content/themes/twentyfifteen/404.php 然后…

JAVA基础 - 数据库编程

目录 一. 简介 二. 数据持久化 三. 安装MySQL 四. JDBC API 五. 三个重要接口 一. 简介 数据库编程是指使用编程语言与数据库进行交互&#xff0c;以实现数据的存储、检索、更新、删除等操作。 在数据库编程中&#xff0c;常见的任务包括&#xff1a; 连接数据库&#x…

Spring统一返回类型中关于String的问题

文章目录 1. 问题铺垫2. 解决方法3. 问题分析4 解决方法解释 1. 问题铺垫 首先设置了以下代码统一处理返回类型 ControllerAdvice public class ResponseAdvice implements ResponseBodyAdvice {Overridepublic boolean supports(MethodParameter returnType, Class converte…

GuLi商城-新增商品-获取分类下所有分组以及属性

/*** 根据分类id查询出所有的分组以及这些组里面的属性* @param catelogId* @return*/ @Override public List<AttrGroupWithAttrsVo> getAttrGroupWithAttrsByCatelogId(Long catelogId) {//1、查询分组信息List<AttrGroupEntity> attrGroupEntities = this.list(…

SwiftUI 中掌握 ScrollView 的使用:滚动可见性

文章目录 前言视图修饰符应用场景可见性完整示例ContentViewVideoPlayerViewScrollViewVisibilityApp 总结 前言 我们的滚动 API 中又有一个重要的新增功能&#xff1a;滚动可见性。现在&#xff0c;你可以获取可见标识符列表&#xff0c;或者快速检查并监控 ScrollView 内视图…

一文彻底搞懂 Fine-tuning - 超参数(Hyperparameter)

最近这一两周看到不少互联网公司都已经开始秋招提前批了。不同以往的是&#xff0c;当前职场环境已不再是那个双向奔赴时代了。求职者在变多&#xff0c;HC 在变少&#xff0c;岗位要求还更高了。 最近&#xff0c;我们又陆续整理了很多大厂的面试题&#xff0c;帮助一些球友解…

【Unity】web gl inputFied 中文输入,同时支持TextMeshInputFied,支持全屏

同时支持TextMeshInputFied&#xff0c;支持全屏。 使用github包【WebGLInput】&#xff1a;https://github.com/kou-yeung/WebGLInput 需要资源的在这里也可以下载 https://download.csdn.net/download/weixin_46472622/89600795 用于unity web gl 中文输入&#xff0c;只需…

本地项目提交到Gitee

在项目目录 右键 git bash here 可以在黑屏输入命令 也可以在项目里面 命令都是一样的 要排除哪些 git add . 添加所有文件 git commit -m "Initial commit" 提交到本地 git remote add origin https://gitee.com/xxxx/xxxx.git 添加远程仓库 …

2-54 基于matlab的模糊自适应PID控制器

基于matlab的模糊自适应PID控制器&#xff0c;PID参数的整定必须考虑到在不同时刻三个参数的作用及相互之间的关系。在线实时模糊自整定PID算法的基础上&#xff0c;通过计算当前系统e和误差变化率ec&#xff0c;利用模糊规则进行模糊推理&#xff0c;查询模糊矩阵表进行参数调…

xss漏洞原理及利用【万字详解】

文章目录 url处XSS图片处XSS攻击svg-xss概念复现 pdf-xss概念复现 游览器翻译-xssflash-xss概念常见造成xss中的swf文件函数举例说明&#xff1a; cookie的获取概念代码审计复现 cookie的获取概念代码审计复现 页面信息获取概念条件复现 xss配合MSf钓鱼概念复现 XSS修复对危险字…

47 集合操作与运算

1 增加与删除集合元素 集合对象的 add() 方法可以增加新元素&#xff0c;如果该元素已存在则忽略该操作&#xff0c;不会抛出异常&#xff1b;update() 方法合并另外一个集合中的元素到当前集合中&#xff0c;并自动去除重复元素。 s {1, 2, 3} print(s) s.add(3) # 增加元…

C# 设计模式之装饰器模式

总目录 前言 装饰器模式的主要作用就是扩展一个类的功能&#xff0c;或给一个类添加多个变化的情况。学习面向对象的都知道&#xff0c;如果想单纯的给某个类增加一些功能&#xff0c;可以直接继承该类生成一个子类就可以。应对一些简单的业务场景继承也就够了&#xff0c;但是…

学习笔记-优化问题

目录 一、目前的问题 1、axios 2、跨域问题 3. 路由安全 二、解决问题 1. 跨域问题 2. 优化URL devServer 1. 配置 devServer 2. 修改请求路径 3. 重启 vue 4. 测试 5. pathRewrite 6. 重启 7. 测试 3. 优化 res.data 4. 判断状态码 5. 引入axios 1. 创建自…

【C++】2.C++入门(2)

文章目录 6.引用6.1 引用概念6.2 引用特性6.3 使用场景6.4 const引用&#xff08;常引用&#xff09;6.5 引用和指针的区别 7.inline7.1inline代码举例&#xff1a;7.2inline代码错误示范7.3实现一个ADD宏函数的常见问题&#xff1a; 8.nullptr 6.引用 6.1 引用概念 引用不是…

Yolov8在RK3588上进行自定义目标检测(三)

参考 Yolov8在RK3588上进行自定义目标检测(一) Yolov8在RK3588上进行自定义目标检测(二) best.onnx转yolov8.rknn onnx转rknn需要用到rknn-toolkit2&#xff0c;这个工具暂时不支持windows&#xff0c;所以我们移步linux&#xff0c;我用的是虚拟机创建的ubuntu20.4的系统&a…