文件操作和IO

news2024/11/22 23:03:39

一.文件的概念:

狭义的文件指:硬盘上的文件和目录

广义上的文件指:计算机中的很多软硬件资源

路径:

  1. 绝对路径:以c:d盘符开头的路径,比如c:/Intel/Logs/text.txt

  1. 相对路径:以当前所在的目录为基准,以.或者..开头(.)有时候可以省略,找到指定的路径

假设当前的工作目录是c:/MyDrivers,定位到update这个目录,就可以表示成./update

同样是定位到c:/相对路径写作./MyDrivers/update,如果工作目录是c:/MyDrivers,相对路径写作./update,如果工作目录是c:/MyDrivers/tmp,相对路径写作../update,如果工作目录是c:/MyDrivers/tmp/123,相对路径写作../../update。

二.Java对于文件的操作:

  1. 针对文件系统的操作(文件的创建,删除,重命名)

  1. 针对文件内容操作(文件的读和写)

java标准库,提供了一个File这个类

public static void main(String[] args)throws IOException {
        File file = new File("c:/intel/Logs/cat.txt");//这个文件不一定是真实存在的
        System.out.println(file.getName());//文件名
        System.out.println(file.getPath());
        System.out.println(file.getAbsolutePath());//文件的绝对路径
        System.out.println(file.getParent());//除去文件名的路径
        System.out.println(file.isFile());//判断是不是文件
        System.out.println(file.isDirectory());//判断是不是目录
        file.createNewFile();//创建这样的一个文件出来
        System.out.println(file.isFile());
        file.delete();//删除改文件
    }

 public static void main(String[] args) {
        File file=new File("d:/123/giteedemo/util11/in");//创建1级目录
        file.mkdir();
    }
public static void main(String[] args) {
        File file=new File("./in/aaa/bbb");
        file.mkdirs();
    }

三.针对文件内容:使用流对象进行操作

Java标准库的流对象从类型上分为两个大类:

  1. 字节流:

InputStream FileInputStream

OutputStream FileOutputStream

  1. 字符流

Reader FileReader

Writer FileWriter

这些类的使用方式非常固定,核心就是四个操作

  1. 打开文件(构造对象)

  1. 关闭文件(close)

  1. 读文件(read) 针对InputStream/Reader

  1. 写文件(write)针对OutputStream/Writer

 public static void main(String[] args)throws IOException {
        InputStream inputStream=new FileInputStream("c:/Intel/text2.txt");
        while(true)
        {
            int a=inputStream.read();

            if(a==-1)//表示读取到文件末尾
            {
                break;
            }
            System.out.println((byte)a);//实际上每次读一个字节我们再强转成byte
        }
        inputStream.close();

    }

read 无参数版本,一次读一个字节

read 一个参数版本,把读到的内容填充到参数的这个字节数组里,只要字节数够每次读取的就是这个数组的大小,假设数组大小是1024,那么要读取的数据字节数够的情况下,一次就读124,如果不够124个字节的话,那么这次读取,剩下多少就读多少

 public static void main(String[] args)throws IOException {
        try(InputStream inputStream=new FileInputStream("c:/MyDrivers/pig.jpg"))
        {
            while(true)
            {
                byte[]buffer=new byte[1024];//每次尽力读1024
                int length=inputStream.read(buffer);//返回每次读取的字节数
                System.out.println(length);
                if(length==-1)
                {
                    break;
                }
                //for(int i=0;i<length;i++)//文件读取的内容
                //{
                   // System.out.printf("%x\n",(byte)buffer[i]);
               // }

            }
        }
    }

最后读取的时候只有377个字节了,所以只读了377个。

像这种读取方式有什么好处呢?单次IO操作,是要访问硬盘/IO设备,单次操作就是比较消耗时间的,如果频繁进行这样的IO操作,肯定就更耗时了,单次IO时间是一定的,如果能缩短IO的次数,此时就可以提高程序的整体效率了,每次只读一个字节,循环次数很高,read次数也很高,但一次 读1024个字节,循环次数就降低很多了,read次数变少了。

read(三个参数版本类型)和一个参数版本类似,往数组里的一部分区间里填充

read的无参数版本,按理说每次读取的是一个字节,返回一个byte就行了,但是实际上返回的是int,因为除了要表示byte里的(-128-127)这样的情况之外,还需要表示一个特殊情况-1,这个情况表示读取文件结束了(读到文件末尾了)

我们来看一下文件里内容是什么

我们再来看一下打印结果

我们看到这些数字其实就是love的ascii码值

当文本内容是兄弟时,我们看一下读取结果

这里我们需要注意一件事情:

public static void main(String[] args)throws IOException {
            InputStream inputStream=new FileInputStream("c:/Intel/text2.txt");
        while(true)
        {
            int a=inputStream.read();

            if(a==-1)//表示读取到文件末尾
            {
                break;
            }
            System.out.printf("%x"+" ",(byte)a);//实际上每次读一个字节我们再强转成byte
        }
        inputStream.close();

    }

我们看到每次我们都需要close(),含义是关闭文件,那么这里的关闭文件又起到了什么作用呢?进程->在内核里,使用PCB这样的数据结构来表示进程,一个线程对应一个PCB,一个进程可以对应一个PCB,也可以对应多个,PCB有一个重要的属性,文件描述符表(相当于一个数组)记录了该进程打开了哪些文件(即使一个进程里有多个线程多个PCB,也没关系,共同用一个文件描述符表)

文件描述符表里的每个元素都是内核里的一个file_struct对象,这个对象就表示一个打开了的文件,每次打开文件操作,就会在文件描述符表中,把这个信息放进去,每次关闭文件,也就会把这个文件描述符表对应的表项给释放掉,如果没有close,对应的表项,没有及时释放,虽然java有GC,GC操作会在回收这个outputStream对象的时候去完成这个释放操作,但是这个GC不一定及时,如果不手动释放,意味着文件描述符表可能很快就被占满了,(这个数组,不能自动扩容,存在上限)如果占满了以后,后面再次打开文件,就会打开失败。

为了防止我们遗忘掉close,我们采取了一种更好的写法

  try(InputStream inputStream=new FileInputStream("c:/Intel/text2.txt"))
            {
            while(true)
            {
              int a=inputStream.read();

              if(a==-1)//表示读取到文件末尾
              {  
                break;
              }
              System.out.printf("%x"+" ",(byte)a);//实际上每次读一个字节我们再强转成byte
             }
        

        }

我们将内容放到try语句块里,这个写法虽然没有显式的写close,实际上是会执行的,只要try语句快执行完毕,就可以自动执行到close,不是随便拿一个对象放到try()里就能自动释放,需要满足一定的要求。

实现了Closeable接口的类才可以放到try的()被自动关闭,这个接口提供的方法就是close方法。

使用了InputStream来读文件,还可以使用OutputStream来写文件。

 public static void main12(String[] args)throws IOException {

        try (OutputStream outputStream = new FileOutputStream("c:/Intel/text.txt")) {
            outputStream.write('h');
            outputStream.write('e');


        }
    }

我们可以看原本是“兄弟”现在是he.

我们接下来再来看一下Reader,Writer按字符读取和写的用法(适合读文本文件)

我们先来看一下我们text的文件里有啥

public static void main13(String[] args)throws IOException {
        Reader reader=new FileReader("c:/Intel/text.txt");
        while(true)
        {
            int a=reader.read();
            if(a==-1)
            {
                break;
            }
            System.out.println(a);
        }

    }

我们看一下打印结果:

这是读文件,我们再来看一下写文件

public static void main17(String[] args)throws IOException {
        try (Writer write = new FileWriter("c:/Intel/text.txt")) {

            write.write("同志再见");
        }
    }

我们将文本里写入“同志再见”

新写入的内容会覆盖掉原来的内容。

另外像这种写操作,我们在最后最好是加上flush语句

 write.flush();

也就是这样

public static void main999(String[] args)throws IOException {
        try (Writer write = new FileWriter("c:/Intel/text.txt")) {

            write.write("同志再见");
            write.flush();
        }
    }

因为像这种写操作,其实是先写到缓冲区里,写操作执行完了,内容可能还在缓冲区里,还没有真的进入硬盘,close操作,就会触发缓冲区的刷新(刷新操作,就是把缓冲区里的内容写到硬盘里),除了close方法,还可以通过flush方法,也能起到刷新缓冲区的效果。

Scanner 是搭配流对象进行使用的

  Scanner scaner=new Scanner(System.in);//System.in其实就是一个输入流对象
 public static void main(String[] args)throws IOException {
        try(InputStream inputStream=new FileInputStream("c:/Intel/text.txt"))
        {
            Scanner scanner=new Scanner(inputStream);//从文件里读
              while(scanner.hasNext())
              {
                                  
                String s = scanner.next();
                System.out.println(s);
               }                  
            

        }
    }

文件内容:

打印结果:

四.两个小程序的实现

  1. 扫描指定目录,并找到名称中包含指定字符的所有普通文件(不包含目录),并且询问用户是否要删除该文件。

ublic static Scanner scan=new Scanner(System.in);
    public static void main(String[] args) {

        System.out.println("请输入路径");
        String basepath=scan.next();
        File root=new File(basepath);
        if(!root.isDirectory())
        {
            System.out.println("输入有误");
            return;
        }
        System.out.println("请输入你想删除的文件");
        String target=scan.next();
        find(root,target);

    }
    public static void find(File root,String target) {
        //System.out.println(root.getAbsolutePath());
        File[] files = root.listFiles();、//列举出当前目录所包含的东西
        if (files == null) {//如果当前目录为空,就返回
            return;
        }
        for (File file : files) {

            if (file.isDirectory()) {//如果是目录,就继续递归
                find(file, target);
            } else {
                if (file.getName().contains(target)) {//包含指定字符的文件
                    System.out.println("请确认是否要删除:删除请按yes,取消删除请按No");
                    String user = scan.next();
                    if (user.equals("yes")) {
                        file.delete();
                        System.out.println("删除成功");

                    } else {
                        System.out.println("取消删除");

                    }


                }
            }
        }
    }
}

  1. 进行普通文件的复制:

思路:把第一个文件按照字节依次读取,把结果写入到另一个 文件中

public static Scanner scan=new Scanner(System.in);
    public static void main(String[] args) {
        System.out.println("请输入想要想要复制的文件:");
        String wen=scan.next();
        File file=new File(wen);
        if(!file.isFile())
        {
            System.out.println("文件不存在");
            return;
        }
        System.out.println("请输入文件复制到的路径");
        String lu=scan.next();
        File filelu=new File(lu);
        if(filelu.isFile())
        {
            System.out.println("您当前输入的目标路径有误");
            return;

        }
        try(InputStream inputStream=new FileInputStream(wen); OutputStream outputStream=new FileOutputStream(lu))
        {
            while(true)
            {
                int a=inputStream.read();
                if(a==-1)
                {
                    break;

                }
                outputStream.write(a);
            }
            System.out.println("复制文件成功");

        }catch(IOException e)
        {
            e.printStackTrace();
        }


    }
}

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

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

相关文章

Vue - 完美解决小数的四则运算(加减乘除)导致精度丢失问题,提供详细计算示例代码vue数据计算丢失精度

前言 由于 JavaScript 语言的问题,两个小数进行四则运算时,会出现各种问题,一些财务系统是必须要解决的。 本文实现了 完美修复小数计算时,计算错误、精度丢失等问题, 您可以进行任意小数的四则运算,都能保证结果是正确的。 如下图所示,使用了本文提供的方法后,可以形…

ArcGIS修改图斑时替换几何的妙用!不要只会整型要素

我们时常通过整型要素来修改要素的形状&#xff0c;但是有时候我们改变整个要素的形状、位置&#xff0c;还要保留属性不变&#xff0c;那我们就要考虑&#xff0c;高级编辑中的“替换几何”工具了。 01 替换几何原理 1 、“替换几何”工具可以为要素创建全新形状。“替换几何…

【Java】Properties类

文章目录01 初识Properties02 Properties常用方法03 Properties使用案例01 初识Properties 创建这样一个配置文件&#xff1a; 传统方法&#xff1a; public static void main(String[] args) throws IOException {//读取mysql.properties文件&#xff0c;并得到ip、user、pw…

Dubbo集群容错

Dubbo集群容错 1. 集群容错 集群调用失败时&#xff0c;Dubbo 提供的容错方案。 在集群调用失败时&#xff0c;Dubbo 提供了多种容错方案&#xff0c;缺省为 failover 重试。 各节点关系&#xff1a; 这里的 Invoker 是 Provider 的一个可调用 Service 的抽象&#xff0c;I…

n皇后(回溯)

著名的n皇后问题 即在棋盘上任意两个皇后不能在同一行&#xff0c;同一列&#xff0c;或者斜对角线&#xff0c;反斜对角线的位置 以判断&#xff08;5&#xff0c;1&#xff09;位置为例 往右下方&#xff08;斜对角线&#xff09;一连串的位置 &#xff08;5&#xff0c;1&…

Naive-UI自定义TabPane样式

前言前端开发通常使用 第三方 UI 组件库&#xff0c;像大家熟悉的 Element-UI、AntD Vue 等最近发现一个 还比较好用的 组件库 Naive-UI 传送门 &#xff0c;Vue 3 组件库&#xff0c;使用 TypeScript &#xff0c;用起来感觉还不错&#xff0c;它的主题也可以切换 &#xff08…

首款自研成像雷达发布!国产玩家赋能智能驾驶“第四类”感知

4D成像雷达赛道的“战火”正在不断升级。 高工智能汽车研究院预计&#xff0c;4D成像雷达将从2023年初开始小规模前装导入&#xff0c;预计到2024年&#xff0c;定点/搭载量有望突破百万颗&#xff0c;到2025年占全部前向毫米波雷达的比重或超过40%。 伴随着中国自动驾驶的渗…

Java多线程:多线程 Thread 类 中常用的方法的使用

Java多线程&#xff1a;多线程 Thread 类 中常用的方法的使用 每博一文案 日本有一位方丈曾在其寺庙的公告栏上写下一句标语&#xff1a; ”没有失败的人生才最失败。“ 深以为然&#xff0c;不上高山&#xff0c;不知平地&#xff0c;不经大海&#xff0c;不懂宽阔的涵义&…

很少人知道的7个极酷HTML元素

搜索很酷的HTML元素&#xff0c;尤其是当您不知道要查找什么时&#xff0c;通常就像被扔进一堆垃圾中一样动图别担心&#xff0c;我为你做了肮脏的工作&#xff01;在浏览了看似无穷无尽的HTML元素之后&#xff0c;我挖出了一些很少使用的宝石&#xff01;1. meter&progres…

多线程Monitor工作原理

&#x1f34e;1. 什么是Monitor?我们都知道synchronized的作用是用来保证修饰的代码或者方法执行有且只有一个线程执行&#xff0c;也就是锁。那么在执行被锁住的方式时&#xff0c;synchronized就需要通过monitor来记录和保证锁的状态。所以monitor这里的作用其实就是起到了控…

RFID固定资产管理系统实现批量“秒”级盘点

面对成千上万&#xff0c;乃至几十万的固定资产&#xff0c;如何能高效管理&#xff0c;做到管理无漏洞&#xff0c;盘点无错漏呢&#xff1f;很多企业和软件厂商都在考虑这个问题。现如今&#xff0c;随着物联网的发展&#xff0c;企业可批量实现固定资产的秒级盘点&#xff0…

【C++核心编程】C++全栈体系(十一)

C核心编程 第四章 类和对象 七、多态 1. 多态的基本概念 多态是C面向对象三大特性之一 多态分为两类 静态多态: 函数重载 和 运算符重载属于静态多态&#xff0c;复用函数名动态多态: 派生类和虚函数实现运行时多态 静态多态和动态多态区别&#xff1a; 静态多态的函数…

打印机共享遇到的常见问题与解决方法

共享打印机提示错误0X000006d9 解决方法: 1、桌面找到计算机或此电脑,然后再图标上右键选择管理选项菜单; 2、在打开的计算机管理对话框中选择服务和应用程序选项; 3、双击服务和应用程序选项就会打开一个对话框,然后再选择服务菜单双击;

01-JDK、JRE、JVM之间的区别?

1.JDK JDK(Java SE Development Kit)&#xff0c;Java标准开发包&#xff0c;它提供了编译、运⾏Java程序所需的各种⼯具和资源&#xff0c;包括Java编译器、Java运⾏时环境&#xff0c;以及常⽤的Java类库等. JDK安装目录中真正在运行java时起作用的是 bin、include、lib、…

一网打尽链表的经典OJ题!链表必考笔试题第二弹

目录 0.前言 1.合并两个排序链表 1.1 实用小妙招 1.2代码书写 2.链表分割 3.链表的回文结构 4.相交链表 4.1 实用小妙招&#xff08;假定指针法&#xff09; 4.2代码书写 5. 复制带随机指针的链表 0.前言 本文代码及分析图片资源都以上传Gitee&#xff0c;可自取&a…

【Java数据结构】堆与优先级队列(堆)的详解

文章目录 目录 文章目录 一、优先级队列(堆) 1.1优先级队列的概念 二、优先级队列的模拟实现 2.1堆的概念 2.2堆的存储方式 2.3堆的创建 2.4建堆的时间复杂度 2.5堆的插入和删除 三.常用的PriorityQueue介绍 3.1PriorityQueue特性 3.2PriorityQueue常用方法 3.3oj练习 一、优…

CANoe-Model Editor介绍以及如何创建一个服务

Model Editor,模型编辑器,可以打开导入的ARXML文件,编辑现有的或定义新的应用层对象(CO、DO) 什么是CO和DO? Model Editor页面的整体布局为: 在左侧的子窗口中,你可以选择要编辑的内容根据你的选择,相应的内容将显示在右侧根据你在此处的选择,你可以使用其他拆分器来…

Vue--》Vue3的setup语法糖到底香不香?你来看看就知道了

目录 setup语法糖 创建Vue3项目 setup语法糖的使用 快速生成setup语法糖模板 setup语法糖新增的API useSlots()和useAttrs() 顶层await setup语法糖 相信在了解过这篇文章的 setup函数讲解 人会觉得Vue3处理数据变得繁琐了&#xff0c;所有的变量都必须return出来才能使…

8步,用python实现进行自动化评论、点赞、关注脚本

嗨害大家好鸭&#xff01; 我是小熊猫~ 分享这个没啥&#xff0c;就是好玩 这里写目录标题嗨害大家好鸭&#xff01; 我是小熊猫~开发环境代码实现点击此处跳转文末名片获取1.请求伪装2.获取关键词3. 获取作品评论ID采集4. 设置评论相应内容5. 设置点赞操作6. 设置关注操作7. 获…

数据结构实验头歌 第1关:求图的最短路径

任务描述 本关任务&#xff1a;编程实现求图的最短路径 相关知识 最短路径的Dijkstra算法&#xff1a; 求最短路径就是求图中的每一个点到图中某一个给定点&#xff08;认为编号为0的点&#xff09;的最短距离。 具体算法就是初始有一个旧图&#xff0c;一个新图。开始时旧图中…