文件API及其操作

news2024/11/24 7:06:03

这里介绍两类文件操作、三个文件类。包括文件系统操作(File类)、文件内容操作(操作字节流、操作字符流)

1.文件类File

1.1.认识File类

(1)什么是File类呢?其实就是可以操作文件的一个类。通过File类构造一个文件对象,此时就得到了一个文件对象的引用,通过该引用,可以得到该文件的路径、名字;判断该文件对象是文件目录还是目标文件

(2)构造方法

签名说明
File(File parent,String child)根据父目录+孩子文件路径,创建一个新的File实例
File(String pathname)根据文件路径创建一个新的File实例,路径可以是绝对/相对路径
File(String parent,String child)根据父目录+孩子文件路径,创建一个新的File实例,父目录用路径表示

我们常用第二个,pathname就是一个文件路径,绝对路径或者相对路径都可以。

值得注意的点:以上创造的File对象,里面的文件路径,表示的是目录还是最终文件,无论在你的硬盘中是否存在,都不影响,都可以创造出来。

1.2.认识File类的方法

这个有什么用呢?就是在构建好一个文件对象之后,可以通过File类中的方法去操作文件。

(1)返回路径型

返回值类型方法签名说明
StringgetParent()返回File对象的父目录文件路径
StringgetName()返回File对象的纯文件名称
StringgetPath()返回File对象的文件路径
StringgetAbsolutePath()返回File对象的绝对路径
StringgetCanonicalPath()返回File对象的修饰过的绝对路径

(2)返回boolean型

返回值类型方法签名说明
booleanexists()判断File对象描述的文件是否真实存在
booleanisDirectory()判断File对象代表的文件是否是一个目录
booleanisFile()判断File对象代表的文件是否是一个普通文件
booleancreateNewFile()根据File对象,自带创建一个空文件。成功创建后返回true
booleandelete()根据File对象,删除该文件。成功删除后返回true
booleanmkdirs()创建File对象代表的目录,如果必要,会创建中间目录
booleanrenameTo(File dest)进行文件改名,也可以视为我们平时的剪切、粘贴操作

(3)其他类型

返回值类型方法签名说明
voiddeleteOnExit()根据File对象,标注文件将删除,删除动作会到JVM运行结束时
String[ ]list()返回File对象代表的目录下的所有文件名
File[ ]listFiles()返回File对象代表的目录下的所有文件,以File对象表示

在标准库中,还有许多方法,这里就不一一展示了。

很多方法在后续也都会使用到,这里也不做使用的展示,我们接着看后续。

1.3.实例化文本对象

下面介绍三种创造File对象的方式,可以说是不同的情况创造File对象 

(1)文件不存在-以相对路径

这个test666.txt文件在实例化对象时,是不存在的,所以最后一行是显示false。其他的路径是因为我们在创造的时候是以一个相对路径,相对路径的现在位置就是该.java文件的位置。

 public static void main(String[] args) throws IOException {
        File f = new File("./text666.txt");
        System.out.println("该文件名字:"+f.getName());
        System.out.println("这级目录的名字:"+f.getParent());
        System.out.println("文件的路径:"+f.getPath());
        System.out.println("文件的绝对路径:"+f.getAbsolutePath());
        System.out.println("文件的绝对路径2:"+f.getCanonicalPath());//这个需要抛出异常
        System.out.println("文件是否真是存在:"+f.exists());
    }

(2)文件不存在--以绝对路径

(3)文件存在--以绝对路径

我们先在d盘上面创造一个文件

然后以创造文件类的方式打开

 public static void main(String[] args) throws IOException {
        File f = new File("d:/test999.txt");
        System.out.println("该文件名字:"+f.getName());
        System.out.println("这级目录的名字:"+f.getParent());
        System.out.println("文件的路径:"+f.getPath());
        System.out.println("文件的绝对路径:"+f.getAbsolutePath());
        System.out.println("文件的绝对路径2:"+f.getCanonicalPath());//这个需要抛出异常
        System.out.println("文件是否真是存在:"+f.exists());
    }

然后以相对路径打开:

第一个绝对路径就是当前的基准路径(在当前项目运行代码)+相对路径拼接而成

绝对路径2就是:拼接后并进行了一些优化操作。

1.4.创造文件

如果文件不存在,我们创造文件要根据下面的方法 

 

(1)相对路径创造文件

 public static void main(String[] args) throws IOException {
        File f = new File("./test222.txt");
        f.createNewFile();//需要抛出异常
    }

需要抛出异常的原因:(1)给出的路径非法(2)路径权限不足

(2)以绝对路径创造

public static void main(String[] args) throws IOException {
        File f = new File("d:/tttttt.txt");
        boolean bool = f.createNewFile();
        System.out.println(bool);
    }

程序运行后:

文件被真正的创造了出来,如果再运行一次代码,就是返回false,原因是该文件已经存在,无法再创造。

(3)判断文件是目录还是普通文件

 public static void main(String[] args) throws IOException {
        File f = new File("d:/tttttt.txt");
        f.createNewFile();
        System.out.println("文件是否真实存在:"+f.exists());
        System.out.println("文件是否代表目录:"+f.isDirectory());
        System.out.println("文件是否为普通问题:"+f.isFile());
    }

1.5.删除文件

删除文件有两个方法,下面一一介绍如果使用,及使用后的结果。

(1)直接删除文件

 public static void main(String[] args) throws IOException {
        File f = new File("d:/tttttt.txt");
        f.createNewFile();
        boolean bool = f.delete();
        System.out.println(bool);
    }

文件已被删除。

(2)延迟删除

 public static void main(String[] args) throws IOException {
        File f = new File("d:/tttttt.txt");
        f.createNewFile();
        f.deleteOnExit();//等进程结束后再删除文件
        System.out.println("进程结束前"+f.exists());
        Scanner in = new Scanner(System.in);
        in.next();//阻塞进程结束
        System.out.println("进程结束后:"+f.exists());
    }

当输入后,进程就会马上结束

文件也就不存在了。这就是延迟删除,当程序彻底结束后文件才会被删除。

接下来的部分是针对文件的内容进行操作。 操作文件内容的三个固定步骤:以二进制/文本方式打开文件--->读文件/写文件--->关闭文件

2.字节流

这样的意思就是:以二进制的方式打开文件,以字节为单位进行读取数据/写数据。

2.1.以字节流读取文件

所谓读取文件,就是读取文件中的数据,但是不会改变里面的内容

(1)打开文件

要读取数据,第一步就是打开文件。这里需要使用两个类,实例化好了对象,就相当于拿到了一个“流”对象,通过流,就可以随时读取文件数据。

 InputStream file = new FileInputStream("d:/dog111.txt");//以二进制打开文件(文件必须存在)

使用到两个类:

InputStream//抽象父类
FileInputStream//子类

注意点:

1)文件路径代表的文件必须真实存在,否则会抛出异常

2)必须在方法后面声明异常

(2)读取文件内容

打开了文件,接下来就读取文件内容的操作,读取文件内容有下面三种方式:

返回值类型方法签名说明
intread()读取一个字节的数据,返回-1代表读取结束(内容已读取完)
intread(byte[ ] b)最多读取b.length字节的数据到b中,返回时机读到的数量;-1代表读取完
intread(byte[ ],int off,int len)最多读取len-off个字节到b中,从b的off位置开始存放;-1读取完

第一种读取方式:每次读取一个字节

 public static void main(String[] args) throws IOException {
        //1.打开文件
        InputStream file = new FileInputStream("d:/dog111.txt");//以二进制打开文件(文件必须存在)
        //2.读文件
        while (true) {
            int n = file.read();
            if(n==-1) {
                System.out.println("文件读取完毕");
                break;
            }
            System.out.printf("%d ",n);
        }

    }

运行结果 

文件内容:

代码解释:我们采取循环读取的方式进行读取,当读取到-1的时候,说明文件里面的内容都已经被读取完毕了,就可以结束循环。

第二种读取方式:每次读取一个字节数组的数据

 public static void main(String[] args) throws IOException{
        InputStream file = new FileInputStream("d:/dog111.txt");
        byte[] bytes = new byte[1024];
        while (true) {
            int n = file.read(bytes);
            if(n==-1) break;
            for (int i = 0; i < n; i++) {
                System.out.printf("%c ",bytes[i]);
            }
            System.out.println();
        }
    }

这种方法读取数据会比第一种快,而且效率也高,

第三种方式:特定场景使用

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

    }

上述都只是打开了流和读取数据,并没有关闭流,下面介绍关闭流。

2.2.关闭流

第一种方式:

使用try finally,目的是防止程序发生特殊情况,导致没有关闭流。但是这样子冗余,不好看。

 public static void main(String[] args) throws IOException{
        InputStream inputStream = new FileInputStream("d:/dog111.txt");
       try{
           byte[] bytes = new byte[1024];
           while (true) {
               int n = inputStream.read(bytes,0,1024);
               if(n==-1) {
                   break;
               }
               for (int i = 0; i < n; i++) {
                   System.out.printf("%c ",bytes[i]);
               }
           }
       }finally {
           inputStream.close();
       }

    }

第二种方式:

 public static void main(String[] args) throws IOException{
        try (InputStream file = new FileInputStream("d:/dog111.txt")){
            byte[] bytes = new byte[1024];
            while (true) {
                int n = file.read(bytes);
                if(n==-1) break;
                for (int i = 0; i < n; i++) {
                    System.out.print((char) bytes[i]+" ");
                }
            }
        }
    }

将打开流的操作,放在try中。当执行完后,会自动关闭流,也就不不需要在后面加上finally了

2.3.以字节流写文件

 (1)第一次写

public static void main(String[] args)  throws IOException{
        //写文件
        try(OutputStream outputStream = new FileOutputStream("d:/dog111.txt")) {
            outputStream.write(97);
            outputStream.write(98);
            outputStream.write(99);
            outputStream.write(100);
            outputStream.write(101);
        }
    }

再写一次:

第二次写时会覆盖掉文件内的内容。

原因是:打开文件就会把文件原有的内容给覆盖掉。为了解决这个问题,可以使用追加的方式进行打开文件。

3.字符流

接下来的读取/写文件,都是以字节为单位的。 

3.1.读文件

对于读文件,依旧是有三种方式,和上述的字节流类似

 (1) 第一种方式:

 public static void main(String[] args) throws IOException {
        Reader reader = new FileReader("d:/dog111.txt");
        while (true) {
            int n = reader.read();
            if(n==-1) break;
            System.out.print((char)n+" ");
        }
    }

可以读取文字

当去read()的时候,读到的是三个字符的数据,但是返回的时候,会转化成两个字节去接收。

(2)第二种方式: 

3.2.写文件

写文件,和上述是一样的。

 如果直接打开文件,然后去写文件,就会将原有的内容覆盖,所以要使用追加的方式去写。

(1)不追加写

原有内容被覆盖了。也就是第一次写入的时候,接着往下写是不会被覆盖的。

(2)追加写

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

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

相关文章

Hdfs小文件治理策略以及治理经验

小文件是 Hadoop 集群运维中的常见挑战&#xff0c;尤其对于大规模运行的集群来说可谓至关重要。如果处理不好&#xff0c;可能会导致许多并发症。Hadoop集群本质是为了TB,PB规模的数据存储和计算因运而生的。为啥大数据开发都说小文件的治理重要&#xff0c;说HDFS 存储小文件…

LeetCode 139 —— 单词拆分

阅读目录 1. 题目2. 解题思路3. 代码实现 1. 题目 2. 解题思路 定义 d p [ i ] dp[i] dp[i] 表示 s [ 0 , i ] s[0, i] s[0,i] 是否可以被字典中出现的单词拼接&#xff0c;那么状态转移方程为&#xff1a; d p [ i ] t r u e &#xff0c;如果存在任意 j ∈ [ 0 , i − 1…

无人机+飞行汽车:低空经济新引擎,有望爆发式增长

无人机和飞行汽车作为低空经济的新引擎&#xff0c;正在引领一场全新的交通革命。随着技术的不断进步和政策的支持&#xff0c;低空经济有望成为未来经济发展的重要领域&#xff0c;实现爆发式增长。 首先&#xff0c;无人机和飞行汽车具有独特的优势和应用场景。无人机可以在…

数据结构与算法-单向环形链表与约瑟夫问题

1.简介 单向环形链表&#xff0c;闭合的形成一个环。 单向环形链表的一个应用场景是约瑟夫问题。 约瑟夫问题为&#xff1a;设编号为1&#xff0c;2&#xff0c;…&#xff0c;n的n个人围坐一圈&#xff0c;约定编号为k(1<k<n)的人从1开始报数&#xff0c;数到m的那个人…

可完成两个变量数值的交换的两种方式【swap函数定义及调用的两种方式】

既然传值调用无法完成两个变量数值的交换&#xff0c;那么可完成该任务的正确方式有以下两种&#xff1a; 方式一&#xff1a;传址调用 //方式一&#xff1a;传址调用 #include <stdio.h>void swap(int* p1, int* p2);int main() {int a 5;int b 9;int* pointer_1 &…

【iOS】pthread、NSThread

文章目录 前言一、pthread 使用方法pthread 其他相关方法 二、 NSThread创建、启动线程线程相关用法线程状态控制方法NSThread 线程安全和线程同步场景 线程的状态转换 前言 五一这两天准备将GCD相关的知识完&#xff0c;同时NSOperation与NSThread、pthread也是相关知识&…

240503-关于Unity的二三事

240503-关于Unity的二三事 1 常用快捷键 快捷键描述CtrlP播放/停止Ctrl1打开Scene窗口Ctrl2打开Game窗口Ctrl3打开Inspect窗口Ctrl4打开Hierarchy窗口Ctrl5打开Project窗口Ctrl6打开Animation窗口 2 关联VisualStudio2022 3 节约时间&#xff1a;将最新声明的参数移动到最上…

MySQL-集群1

一、为什么要用mysql集群&#xff1f;&#xff1a; mysql单体架构在企业中很少用&#xff0c;原因&#xff1a;①会形成单点故障&#xff0c;没有高可用的效果&#xff1b;②mysql本身是一个I/O能力比较差&#xff0c;并发能力比较差的应用服务&#xff0c;在较高规模的网络I/…

C#知识|将选中的账号信息展示到控制台(小示例)

哈喽,你好啊,我是雷工! 上篇学习了控件事件的统一关联, 本篇通过实例练习继续学习事件统一处理中Tag数据获取、对象的封装及泛型集合List的综合运用。 01 实现功能 在上篇的基础上实现,点击选中喜欢的账号,选中按钮底色变为蓝色,当选择完毕,点击保存选择时,将选中的…

Java InputStream实战指南:轻松读取、操作文件流

哈喽&#xff0c;各位小伙伴们&#xff0c;你们好呀&#xff0c;我是喵手。运营社区&#xff1a;C站/掘金/腾讯云&#xff1b;欢迎大家常来逛逛 今天我要给大家分享一些自己日常学习到的一些知识点&#xff0c;并以文字的形式跟大家一起交流&#xff0c;互相学习&#xff0c;一…

Themis新篇章:老牌衍生品协议登陆Blast L2,探索全新经济模型

本文将深入分析 Themis 的最新经济模型&#xff0c;探讨其核心概念和机制、优势与创新之处、风险与挑战。 一、引言 随着区块链技术的不断发展&#xff0c;DeFi 衍生品项目逐渐成为市场的焦点。而用户体验的革新&#xff0c;进一步的金融创新&#xff0c;去中心化治理方案的优…

Sharding Capital: 为什么投资全链流动性基础设施 Entangle ?

写在前面&#xff1a;Entangle 项目的名称取自于量子纠缠(Quantum entanglement)&#xff0c;体现了项目对于构建连接、关联和互通的愿景。就像量子纠缠将不同的粒子联系在一起&#xff0c;Entangle 旨在通过其跨链流动性和合成衍生品的解决方案将不同的区块链网络连接在一起&a…

Redis高并发可用-主从复制,集群

Redis高并发可用 1 复制 默认情况下&#xff0c;Redis都是主节点。每个从节点只能有一个主节点&#xff0c;而主节点可以同时具有多个从节点。复制的数据流是单向的&#xff0c;只能由主节点复制到从节点。 1.1 复制的拓扑结构 一主一从&#xff1a; 主一从结构是最简单的…

Go 语言(三)【面向对象编程】

1、OOP 首先&#xff0c;Go 语言并不是面向对象的语言&#xff0c;只是可以通过一些方法来模拟面向对象。 1.1、封装 Go 语言是通过结构体&#xff08;struct&#xff09;来实现封装的。 1.2、继承 继承主要由下面这三种方式实现&#xff1a; 1.2.1、嵌套匿名字段 //Add…

ue引擎游戏开发笔记(28)——实现第三人称越肩视角

1.需求分析 实现一个第三人称越肩视角 2.操作实现 1.思路&#xff1a;建立一个弹簧臂和摄像机&#xff0c;调整两者位置达到越肩效果。 2.直接在蓝图操作&#xff1a;添加摄像机和弹簧臂&#xff1a; 3.对弹簧臂勾选使用pawn控制旋转&#xff0c;并适当调整摄像机和弹簧臂位置…

QT:输入类控件的使用

LineEdit 录入个人信息 #include "widget.h" #include "ui_widget.h" #include <QDebug> #include <QString>Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this);// 初始化输入框ui->lineEdit…

电脑崩溃了,之前备份的GHO文件怎么恢复到新硬盘?

前言 之前咱们说到用WinPE系统给电脑做一个GHO镜像备份&#xff0c;这个备份可以用于硬盘完全崩溃换盘的情况下使用。 那么这个GHO镜像文件怎么用呢&#xff1f; 咱们今天详细来讲讲&#xff01; 如果你的电脑系统硬盘崩溃了或者是坏掉了&#xff0c;那么就需要使用之前备份…

Git的基本操作和使用

git分支指令 列出所有本地分支 git branchmaster是绿的 前面有个 表示当前分支是master* 列出所有远程分支 git branch -r列出所有本地分支和远程分支 git branch -a新建一个分支&#xff0c;但依然停留在当前分支 git branch [branch-name]新建一个分支&#xff0c;并切…

Redis__三大日志

文章目录 &#x1f60a; 作者&#xff1a;Lion J &#x1f496; 主页&#xff1a; https://blog.csdn.net/weixin_69252724 &#x1f389; 主题&#xff1a;Redis__三大日志 ⏱️ 创作时间&#xff1a;2024年04月30日 ———————————————— 对于MySQL来说, 有…

政安晨:【Keras机器学习示例演绎】(三十)—— 使用变换器进行视频分类

目录 数据收集 设置 定义超参数 数据准备 构建基于变换器的模型 培训的效用函数 模型训练和推理 政安晨的个人主页&#xff1a;政安晨 欢迎 &#x1f44d;点赞✍评论⭐收藏 收录专栏: TensorFlow与Keras机器学习实战 希望政安晨的博客能够对您有所裨益&#xff0c;如有不…