Java文件操作

news2024/11/20 20:28:25

文章目录

  • 1、文件的基本概念
  • 2、java文件操作
    • 2.1 File概述
    • 2.2 InputStream 和 FileInputStream
    • 2.3 OutputStream 和 OutputStreamWriter

1、文件的基本概念

平时说的文件一般都是指存储在硬盘上的普通文件,形如txt,jpg,mp4,rar等这些文件都可以认为是普通文件,它们都是在硬盘上存储的。

在计算机中,文件可能是一个广义的概念,就不只是包含普通文件,还可以包含目录(把目录称为目录文件),目录就是所谓的文件夹

操作系统中,还会使用文件来描述一些其他的硬件设备或者软件资源。例如操作系统就把网卡这样的硬件设备抽象成为文件,除此之外显示器,键盘、鼠标,操作系统也会把这些设备视为文件,这样做的好处就是为了简化开发。

站在程序员的角度,文件主要分为两大类

  1. 文本文件。里面存储的都是字符,不过文本文件的本质也是存放字节,但是相邻的字节在一起正好能构成一个个的字符。
    类似的,像日常中使用的.txt,.C,.C++,.java等都属于文本文件
  2. 二进制文件。里面存储的都是字节,字节之前完全没有任何关系。
    类似的,像.doc,.ppt,.exe,.zip,.class等都属于二进制文件

针对这两种文件,在编程的时候会存在差异

如何判定一个文件是文本文件还是二进制文件,有一种简单的方法:用记事本打开,如果打开是我们不认识的乱码,就是二进制文件,反之就是文本文件

文本文件:

在这里插入图片描述

二进制文件:

在这里插入图片描述

关于目录结构

在计算机里,保存管理文件,是通过操作系统中的文件系统这样的模块来负责的(Linux 下的文件系统主要有 ext2、ext3、ext4 等文件系统。Linux 还支持其他的 UNIX 文件系统,比如 XFS、JFS、UFS 等,也支持 Windows 的 FAT 文件系统和网络文件系统 NFS 等)

文件系统中,一般是通过"树形"结构来组织磁盘上的目录和文件,我们将这个结构称之为目录树。这里目录树并不是二叉的,而是N叉

在这里插入图片描述

如何在一个文件系统中找到一个具体的文件,操作系统就通过"路径"这样的概念,来描述一个具体文件/目录的位置

这里的路径就有两种描述风格(Windows下,Linux下也是差不多的)

1.绝对路径:以盘符开头
例如
B:\java\IntelliJ IDEA 2020.3.2\bin
D:\抖音\douyin-v1.0.8-win32-ia32-douyin.exe

2.相对路径:以.或者…开头,其中.表示当前路径,…表示当前路径的父目录(上级路径)
谈到相对路径,必须要限定一个基准目录,相对路径就是从基准目录出发,按照指示的路径找到对应文件
例如
以B:\java\IntelliJ IDEA 2020.3.2为基准目录,找到bin,./bin,此处的.就表示当前目录
以B:\java\IntelliJ IDEA 2020.3.2\bin为基准目录,找到B:java\IntelliJ IDEA 2020.3.2,…/,此处的…就表示基准目录的上级目录

即使定位到同一个文件,如果基准目录不同,此处的相对路径也是不同的

Linux中的路径分隔符(/作为分隔符)和Windows中的分隔符(\作为分隔符)是不同的

生活中也有相对路径和绝对路径的概念

在这里插入图片描述

当我在商城需要问路时,问工作人员奶茶店在哪里,工作人员的描述就有两种风格

绝对路径: 无论我站在商城的哪个位置,工作人员都按照从进入西门开始描述
例如,从进入西门开始,向前走50m,向右走200m,再向前走100,最后再向右走100m就能到达

相对路径: 根据我所处的位置进行不同的描述
例如我处在位置1,向右走200m,再向前走100,最后再向右走100m就能到达
处在位置2,向前走100,最后再向右走100m就能到达
处在位置3,向右走100m就能到达

2、java文件操作

Java 中通过 java.io.File 类来对一个文件(包括目录)进行抽象的描述。注意,有 File 对象,并不代表真实存在该文件

2.1 File概述

File 类中的常见属性、构造方法和方法

属性

修饰符及类型属性说明
static StringpathSeparator依赖于系统的路径分隔符,String 类型的表示
static charpathSeparator依赖于系统的路径分隔符,char 类型的表示

构造方法

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

方法

修饰符及返回值类型方法说明
StringgetParent()返回 File 对象的父目录文件路径
StringgetName()返回 FIle 对象的纯文件名称
StringgetPath()返回 File 对象的文件路径
StringgetAbsolutePath()返回 File 对象的绝对路径
StringgetCanonicalPath()返回 File 对象的修饰过的绝对路径
booleanexists()判断 File 对象描述的文件是否真实存在
booleanisDirectory()判断 File 对象代表的文件是否是一个目录
booleanisFile()判断 File 对象代表的文件是否是一个普通文件
booleancreateNewFile()根据 File 对象,自动创建一个空文件。成功创建后返回 true
booleandelete()根据 File 对象,删除该文件。成功删除后返回 true
voiddeleteOnExit()根据 File 对象,标注文件将被删除,删除动作会到JVM 运行结束时才会进行
String[]list()返回 File 对象代表的目录下的所有文件名
File[]listFiles()返回 File 对象代表的目录下的所有文件,以 File 对象表示
booleanmkdir()创建 File 对象代表的目录
booleanmkdirs()创建 File 对象代表的目录,如果必要,会创建中间目录
booleanrenameTo(Filedest)进行文件改名,也可以视为我们平时的剪切、粘贴操作
booleancanRead()判断用户是否对文件有可读权限
booleancanWrite()判断用户是否对文件有可写权限

例1:获取文件名,父目录以及文件路径

public class Demo1 {
    public static void main(String[] args) throws IOException { //IOException表示在输入输出时出现了问题
        //和这种写法是一样的  "D:\\test.txt"
        //我的计算机中确实存在这个文件
        File f = new File("D:/test.txt");

        //获取到文件的父目录
        System.out.println(f.getParent());

        //获取文件名
        System.out.println(f.getName());

        //获取到文件路径(构造File的时候指定的路径)
        System.out.println(f.getPath());

        //获取文件的绝对路径
        System.out.println(f.getAbsolutePath());

        //这也是获取文件的绝对路径
        System.out.println(f.getCanonicalPath());
    }
}

结果
============
D:\
test.txt
D:\test.txt
D:\test.txt
D:\test.txt

例2:判断文件是否存在,是否为目录,是否为普通文件

public class Demo2 {
    public static void main(String[] args) {
        File f = new File("D:/test.txt");
        System.out.println(f.exists());//判断文件是否存在
        System.out.println(f.isDirectory());//判断文件是否是目录
        System.out.println(f.isFile());//判断文件是否是普通文件
    }
}

结果
=============
true
false
true

如果文件不存在,则都为false

例3:文件的创建和删除

public class Demo3 {
    public static void main(String[] args) throws IOException {
        //文件的创建和删除
        File f = new File("D:/test.txt");
        f.delete();
        System.out.println("删除文件成功");
        System.out.println(f.exists());
        System.out.println("创建文件");
        f.createNewFile();
        System.out.println("创建文件完成");
        System.out.println(f.exists());
    }
}

结果
======================
删除文件成功
false
创建文件
创建文件完成
true

例4:创建单级目录和多级目录

public class Demo5 {
    public static void main(String[] args) {
        //创建单级目录
        File f = new File("./aaa");
        f.mkdir();
        System.out.println("创建单级目录成功");
        System.out.println(f.isDirectory());

        //创建多级目录
        File f1 = new File("./aaa/bbb/ccc");
        f1.mkdirs();
        System.out.println("创建多级目录成功");
        System.out.println(f1.isDirectory());
    }
}

结果
===============
创建单级目录成功
true
创建多级目录成功
true

2.2 InputStream 和 FileInputStream

InputStream

修饰符及返回值类型方法说明
intread()读取一个字节的数据,返回 -1 代表已经完全读完了
intread(byte[] b)最多读取 b.length 字节的数据到 b 中,返回实际读到的数量;-1 代表以及读完了
intread(byte[] b, int off, int len)最多读取 len - off 字节的数据到 b 中,放在从 off 开始,返回实际读到的数量;-1 代表以及读完了
voidclose()关闭字节流

InputStream 只是一个抽象类,要使用还需要具体的实现类。关于 InputStream 的实现类有很多,基
本可以认为不同的输入设备都可以对应一个 InputStream 类,我们现在只关心从文件中读取,所以使
用 FileInputStream

FileInputStream

构造方法说明
FileInputStream(File file)利用 File 构造文件输入流
FileInputStream(String name)利用文件路径构造文件输入流

例5:以字节流的方式读取文件,一次读取一个字节

public class Demo8 {
    public static void main(String[] args) {
        //构造方法中需要指定打开的文件路径
        //这里的路径可以是绝对路径,也可以是相对路径,还可以是File对象
        try {
            //1.创建对象,同时也是在打开文件
            InputStream inputStream = new FileInputStream("D:/test.txt");
            //2.尝试一个一个字节的读,把整个文件读完
            while (true) {
                int b = inputStream.read();
                if (b == -1) {
                    //-1表示读到了文件末尾
                    break;
                }
                System.out.print(b + " ");
            }
            //3.读完之后,需要关闭文件
            inputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

//文件中存放的是字符abcdef
结果
===========
97 98 99 100 101 102 

在这里插入图片描述

这个代码还有一个缺陷:如果在执行read过程中抛出异常了,就会直接触发catch代码,从而导致close无法执行
更好的做法就是把close放在final里面

例6:

public class Demo8 {
    public static void main(String[] args) {
        //构造方法中需要指定打开的文件路径
        //这里的路径可以是绝对路径,也可以是相对路径,还可以是File对象
        InputStream inputStream = null;
        try {
            //1.创建对象,同时也是在打开文件
            inputStream = new FileInputStream("D:/test.txt");
            //2.尝试一个一个字节的读,把整个文件读完
            while (true) {
                int b = inputStream.read();
                if (b == -1) {
                    //-1表示读到了文件末尾
                    break;
                }
                System.out.print(b + " ");
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //3.读完之后,需要关闭文件
            try {
                inputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

改进之后,代码是稳妥了,但是整体显得太繁琐。
Java中提供了一个语法:try with resources

例7:

public class Demo8 {
    public static void main(String[] args) {
        try(InputStream inputStream = new FileInputStream("D:/test.txt");) {
            while (true) {
                int b = inputStream.read();
                if(b == -1) {
                    break;
                }
                System.out.println(b);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

结果
==========
97 98 99 100 101 102

在这个代码中,我们并没有显示的调用close,但try会帮我们自动调用,当代码执行完成这里的try语句块之后,就会自动调用close。在try()中,也不是随便什么都能填,只有实现了Closeable接口才能放在try()中,所有的流对象都实现了Closeable接口,所以可以直接放

例8:一次读取若干字节

public class Demo8 {
    public static void main(String[] args) {
    	try(InputStream inputStream = new FileInputStream("D:/test.txt");) {
            //一次读取若干个字节
            while(true) {
                byte[] buffer = new byte[1024];
                //将读取到的数据放在buffer中
                //len表示实际读取到的字节数
                int len = inputStream.read(buffer);
                if(len == -1) {
                    break;
                }
                for(int i = 0; i < len; ++i) {
                    System.out.print(buffer[i] + " ");
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

结果
=============
97 98 99 100 101 102 

inputStream.read(buffer)中的buffer称为输出型参数,这个操作在Java中很少见,但在C/C++中很常见

每次读取磁盘都是比较低效的操作,能一次多读点是更好的

2.3 OutputStream 和 OutputStreamWriter

OutputStream

修饰符及返回值类型方法说明
voidwrite(int b)写入要给字节的数据
voidwrite(byte[]b)将 b 这个字符数组中的数据全部写入 os 中
intwrite(byte[]b, int off,int len)将 b 这个字符数组中从 off 开始的数据写入 os 中,一共写 len 个
voidclose()关闭字节流
voidflush()刷新缓冲区

OutputStream 同样只是一个抽象类,要使用还需要具体的实现类。我们现在还是只关心写入文件中,
所以使用 FileOutputStream

例9:一次写一个字节

public class Demo9 {
    //使用字节流,写文件案例
    public static void main(String[] args) {
        try(OutputStream outputStream = new FileOutputStream("D:/test.txt")) {
            outputStream.write(97);
            outputStream.write(98);
            outputStream.write(99);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

例10:一次写多个字节

public class Demo9 {
    //使用字节流,写文件案例
    public static void main(String[] args) {
        try(OutputStream outputStream = new FileOutputStream("D:/test.txt")) {
            byte[] buffer = new byte[]{97,98,99};
            outputStream.write(buffer);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

按上述写方式打开文件,无论是一次写一个字节,还是一次写多个字节,都会清空原有文件的内容,清空旧的内容,再从起始位置往后写

还有一种用于追加写的流对象,打开之后不清空,从文件末尾开始写
OutputStream outputStream = new FileOutputStream(“D:/test.txt”, true)
第二个参数表示是否追加,true表示追加,默认为false

例11:按照字符读取

ublic class Demo10 {
    public static void main(String[] args) {
        try (Reader reader = new FileReader("D:/test.txt")) {
            //按照字符来读写
            while (true) {
                char[] buffer = new char[1024];
                int len = reader.read(buffer);
                if(len == -1){
                    break;
                }
                //如果这里传入的是byte数组,还可以手动指定一下utf8字符集,避免乱码
                String s = new String(buffer, 0, len);
                System.out.println(s);
            }
        }catch(IOException e) {
            e.printStackTrace();
        }
    }
}

例12:

public class Demo11 {
    public static void main(String[] args) {
        try (Writer writer = new FileWriter("D:/test.txt")) {
            writer.write("xyz");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

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

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

相关文章

Mybatis源码详解

Mybatis源码详解一、JDBC与Mybatis对比JDBC调用Mybatis调用两者对比二、Mybatis资源加载数据源获取SqlSessionFactoryBuilder.buildXMLConfigBuilder.parseXMLConfigBuilder.environmentsElementSQL语句获取1.入口2.两种方式3.XML方式获取SQL3.1 XMLMapperBuilder.parse()3.2 X…

【小白学YOLO】YOLOv3网络结构细致解析

摘要&#xff1a;本文将详细介绍Yolov3的网络结构相关内容。Yolov3 网络结构 在博客“Yolo发展历史及网络结构”中我们已经详细的解释了Yolov1的网络结构&#xff0c;并简要的提到了Yolov2与Yolov3对于网络结构的改进&#xff0c;本篇博客将详细介绍Yolov3的网络结构&#xff…

骑行耳机哪个品牌好,推荐五款最适合骑行佩戴的五款耳机

运动训练是一件非常单调的事情&#xff0c;尤其是你从事的运动节奏感比较强的时候&#xff0c;自身的呼吸频率也会随之加快&#xff0c;调节不过来的时候就很容易呼吸错乱导致运动大幅度下降&#xff0c;这时可以选择一些同当前运动节奏相符的音乐&#xff0c;让音乐在运动的全…

多云管理平台发展的几个阶段

多云管理平台能够无差别地提供统一的资源管理、业务能力和运行维护等功能&#xff0c;从而可以屏蔽掉底层云资源池的差异性&#xff0c;大大降低了用户的建设成本和运行维护成本&#xff0c;因此也是目前算力网络异构云资源池统一管理的主流建设方案。 自Gartner首次提出多云管…

黄金价格走势软件下载,国内十大现货黄金正规平台排名(2022最新榜单)

炒金者想要参与国际现货黄金交易市场中&#xff0c;开户是炒金者现货黄金理财的必经之路&#xff0c;但是依然有不少炒金者谈到开户就会色变&#xff0c;他们担心的不仅仅是开户流程复杂&#xff0c;而是担心开户时遇到的风险难易保证&#xff0c;但实际上大可不必如此&#xf…

Kotlin 中的 inline 和nonline 和crossinline

inline /*** 内联 递归函数无法内联&#xff0c;编译不通过* 函数的 参数 没有 lambda 无需内联--只是减少了方法调用层级 对性能没大影响* 函数的 参数 有 lambda 内联 * 1 不使用内联 在调用端&#xff0c;会生成 Function 对象 完成 lambda的 调用(性能损耗,for 循环 或…

【小程序】微信小程序自定义导航栏及其封装

&#x1f4ad;&#x1f4ad; ✨&#xff1a; 微信小程序自定义导航栏   &#x1f49f;&#xff1a;东非不开森的主页   &#x1f49c;: 因为很多东西来不及去做去看可是时间很快总是赶不上&#xff0c;所以要去成长呀&#x1f49c;&#x1f49c;   &#x1f338;: 如有错误或…

20221116 Dubbo+Zookeeper

DubboZookeeper实现分布式布局加入ZookeeperDubbo编写provider代码&#xff08;简单示例&#xff09;添加依赖代码编写consumer代码&#xff08;简单示例&#xff09;加入依赖代码加入Dubbo管理控制台DubboZookeeper实现分布式布局 加入Zookeeper 在服务器端使用docker 下载Z…

Word处理控件Aspose.Words功能演示:使用 C# 将 Word 文档转换为 Markdown

如今&#xff0c;大量的文章、博客和文档都是以Markdown ( MD ) 格式编写的。但是&#xff0c;对于大型文档&#xff0c;Markdown 语法通常变得难以记忆和编写。为方便起见&#xff0c;您可以在 MS Word 中编写内容&#xff0c;然后将DOCX或DOC文档转换为 Markdown。为了自动化…

【Redis入门笔记 09】缓存穿透、击穿与雪崩

目录&#x1f349;缓存穿透&#x1f353;缓存击穿&#x1f351;缓存雪崩☕前言&#xff1a; Redis 数据库常常用来充当传统数据库的缓存。一个实际的场景是当用户的请求过来&#xff0c;先去查缓存中的数据&#xff0c;如果缓存中不存在&#xff0c;则再去查询数据库&#xff…

快速查找qt pro文件中的用qmake language写的库函数

qt函数分为test函数和replace函数&#xff1a;qmake language 内置函数 自定义函数 defineTest(testfunctionname) defineReplace(repacefunctionname)_丘上人的博客-CSDN博客 qt为qmake language提供了内建函数&#xff08;用C写的逻辑&#xff09;和用qmake language写的库函…

html移动端实现手写签名,signature手写签名实现,微信公众号浏览器html手写签名实现

前言 html移动端手写自动横竖签名实现&#xff0c;并base64图片格式获取&#xff1b; 横竖根据屏幕宽高自动平铺。 效果图 图一 图二 实现 如下代码直接复制成.html文件打开即可预览效果 <!DOCTYPE html> <html><head><title>手写签名</title&…

适合中小企业的ERP管理软件如何选择?

在选择ERP系统时&#xff0c;我们可以按照这三个维度&#xff0c;然后再按照需求去选择ERP系统。 市面上ERP软件大概可以分为三大类&#xff1a; ① 标准ERP应用&#xff1a;功能比较固定&#xff0c;难以满足个性化需求&#xff0c;二次开发难度很高&#xff1b; ② 找外包/…

SQL 的执行流程是什么样的

在选择存储引擎时&#xff0c;应该根据应用系统的特点选择合适的存储引擎。对于复杂的应用系统&#xff0c;还可以根据实际情况选择多种存储引擎进行组合。 以下是几种常用的存储引擎的使用环境。 InnoDB : 是 Mysql 的默认存储引擎&#xff0c;用于事务处理应用程序&#xf…

浅谈薄膜行业MES解决方案

随着国家节能减排的号召&#xff0c;新能源电动汽车蓬勃发展&#xff0c;带动整个锂电行业的崛起&#xff0c;锂电池的结构中&#xff0c;隔膜是关键的内层组件之一。隔膜的性能决定了电池的界面结构、内阻等&#xff0c;直接影响电池的容量、循环以及安全性能等特性&#xff0…

数据中台选型必读(四):要想中台建的好,数据模型得做好

在数据中台构建之前&#xff0c;分析师经常发现自己没有可以复用的数据集&#xff0c;不得不使用原始数据依次进行数据的清洗、加工、计算指标。 重复进行原始数据的清洗加工 由于业务部门的分析师大多是非技术出身&#xff0c;写的SQL可能比较差&#xff0c;多层嵌套对后台的…

【教学类-13-02】20221115《数字色块图5*7*8横板》(中班主题《》)

效果展示 背景需求&#xff1a; 前期中3班制作5*7 *9张数字图&#xff0c;发现三个问题&#xff1a; 1、数量太多&#xff0c;填不完——每人9张调整为每人4张&#xff08;一张A4两份作业&#xff09; 2、数字太浅&#xff0c;看不清——5*7的提示数字是灰色&#xff0c;数字…

WeNet更新:喜马拉雅团队在 WeNet 中支持 Squeezeformer

WeNet在正式发布两年的时间里&#xff0c;成为非常热门的ASR生产工具&#xff0c;其面向生产的属性更是深受工业界的好评。近期&#xff0c;喜马拉雅团队在WeNet中支持了Squeezeformer的相关工作。本文由喜马拉雅珠峰智能实验室撰写&#xff0c;介绍了Squeezeformer论文的复现细…

vant_vant引入

目录vant官网使用vant[1]导入vant 的所有组件[2] 按需引入组件[3]自动按需引入组件使用过程中遇到的问题[1]问题1-版本冲突vant官网 vant2.0官网 使用vant 参考vant官网–>快速上手–>通过npm安装/引入组件 [1]导入vant 的所有组件 [1] 安装 vant &#xff1a;npm i va…

基于matlab的MRC最大合并比误码率仿真,包括维特比译码,MRC,中继

目录 1.算法概述 2.仿真效果预览 3.核心MATLAB代码预览 4.完整MATLAB程序 1.算法概述 最大比合并&#xff08;Maximal Ratio Combining&#xff0c;MRC&#xff09;是分集合并技术中的最优选择&#xff0c;相对于选择合并和等增益合并可以获得最好的性能&#xff0c;其性能…