文件操作和IO流

news2024/12/27 13:04:39

  前言👀~

上一章我们介绍了多线程进阶的相关内容,今天来介绍使用java代码对文件的一些操作

文件(file)

文件路径(Path)

文件类型

文件操作

文件系统操作(File类)

文件内容的读写( 流对象)

字符流(文本文件)

Reader类

Writer类

字节流(二进制文件)

InputStream类

outputStream类

字节流转为字符流

缓冲区(buffer)


如果各位对文章的内容感兴趣的话,请点点小赞,关注一手不迷路,讲解的内容我会搭配我的理解用我自己的话去解释如果有什么问题的话,欢迎各位评论纠正 🤞🤞🤞

12b46cd836b7495695ce3560ea45749c.jpeg

个人主页:N_0050-CSDN博客

相关专栏:java SE_N_0050的博客-CSDN博客  java数据结构_N_0050的博客-CSDN博客  java EE_N_0050的博客-CSDN博客


文件(file)

操作系统会将很多的硬件设备以及软件资源抽象成"文件"统一进行管理,但是大部分情况"文件"指的是硬盘上的文件,也就是对硬盘的一种抽象。硬盘有机械硬盘(HDD)和固态硬盘(SSD),固态硬盘的效率比机械硬盘高,里面都是集成程度很高的芯片(类似cpu,内存),我们的电脑一般自带的都是固态硬盘,想放更多资料可以加个机械硬盘


文件路径(Path)

编程的时候我们通过文件的方式操作硬盘,如上面所说把硬盘抽象出来进行操作。计算机中有很多文件,我们通过"文件系统"(操作系统提供的模块)进行组织和管理,操作系统中使用目录(文件)这样的结构来组件文件,采用树形结构,想想也好理解树有根结点理解为硬盘,点进去就是目录/文件,也就是根节点的子结点以此类推。用目录的层次结构来描述文件所在的位置称为"路径",C:\Windows\System32,类似这样的字符串,可以看出当前文件在哪个目录下

1.绝对路径:就是上面这个以你的盘开头的C:\Windows\System32

2.相对路径:前提是指定了一个目录,作为基准目录,从基准目录出发沿着路线找你指定的文件,以 .(当前目录)或者 ..(当前目录的上一级目录)开头,.后面跟的路径代表咋们是在同一个文件下的,..后面跟的路径,..代表是后面路径的爹

文件类型

文件,根据其保存数据的不同,也经常被分为不同的类型,在编程角度,我们一般划分为文本文件和二进制文件,不管属于哪个在计算机中这些数据都是以二进制进行存储的

1.文本类型:文件中保存的数据,都是字符串,保存的内容都属于合法的字符

2.二进制类型文件中保存的数据,都是二进制,保存的内容不一定是合法的字符

首先说什么是字符,字符就是字母、数字、符号等书面语言,不合法的字符指的是在某种字符编码下无法正确显示的字符(通常会显示为乱码)字符集则是字符的集合,它会给每一个字符分配一个唯一的编号,例如ASCALL码和Unicode就是字符集,Unicode字符集包含几乎所有已知的文字和符号,字符编码就是将字符转换为计算机能处理的数据,字符编码方式有UTF-8、UTF-16等。所以如果你的文件是通过utf8进行编码的话,此时保存的数据都是utf8编码中合法的字符,那就是文本文件,如果出现不是utf8编码的字符,那就是二进制了

其实判断文件什么类型很简单,打开是乱码就算二进制类型,否则就是文本类型。可以使用记事本去测试,把文件往里丢,看里面的字符你认识不,认识的话一般就是文本类型了,不是的话就是二进制类型。文本文件和二进制文件的代码编写方式不同,要注意区分。下面演示一下乱码


文件操作

分为两类,文件系统的操作,例如创建文件、删除文件、重命名等,也就是你右击文件能干的事,在java中我们可以使用File类也能完成这些操作文件内容的操作,流对象。这里的操作例如读文件、写文件。可以使用例如InputStream和OutPutStream后面进行详细讲解


文件系统操作(File类)


属性:

pathSeparator,表示路径的分隔符就是这个" \ ",windows这个" \ "和" / "都行,Mac和Linux上只能使用 / "作为分隔符。这个属性可以根据当前系统自动变化,又体现了跨平台性

构造方法:

一个File对象,就对应硬盘上的文件,构造对象的时候把文件路径(绝对路径或者相对路径)以及文件扩展名,就是你要操作哪个文件,你把路径丢到file的构造方法即可

方法:

下面是file的方法,后面会进行演示

前五个路径方法演示:

public class Test {
    public static void main(String[] args) throws IOException {
        File file = new File("E:/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.getCanonicalFile());//获取修饰过的绝对路径
    }
}

输出结果

可以发现即使这个文件我没有也没事

getCanonicalFile方法和get Absolute Path方法的区别可以看如下代码

public class Test {
    public static void main(String[] args) throws IOException {
        File file = new File("./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.getCanonicalFile());//获取修饰过的绝对路径
    }
}

输出结果,我把文件路径改成相对路径的时候就有区别了

三个判断文件类型以及文件是否存在方法演示:

public class Test {
    public static void main(String[] args) throws IOException {
        File file = new File("E:/IO");
        System.out.println(file.exists());//判断文件是否存在
        System.out.println(file.isDirectory());//判断文件类型 是否是一个目录
        System.out.println(file.isFile());//判断文件类型 是不是普通文件
    }
}

输出结果

createNewFile()创建文件的方法演示

public class Test {
    public static void main(String[] args) throws IOException {
        File file = new File("E:/IO/text.txt");
        System.out.println(file.createNewFile());
    }
}

输出结果

 delete()和deleteOnExit()方法删除文件的方法有两个并且有区别下面进行演示

public class Test {
    public static void main(String[] args) throws IOException {
        File file = new File("E:/IO/text.txt");
        System.out.println(file.delete());
    }
}

输出结果

public class Test {
    public static void main(String[] args) throws IOException, InterruptedException {
        File file = new File("E:/IO/text.txt");
        Thread.sleep(3000);
        file.deleteOnExit();//等JVM运行结束了再去删除文件
    }
}

输出结果


listFiles()方法获取当前目录下所有文件

public class Test {
    public static void main(String[] args) throws IOException, InterruptedException {
        File file = new File("E:/");
        File[] f = file.listFiles();//获取当前目录下所有文件
        for (File wow : f) {
            System.out.print(wow + " ");
        }
    }
}

输出结果

mkdir()方法在当前目录下创建文件

public class Test {
    public static void main(String[] args) throws IOException, InterruptedException {
        File file = new File("E:/IO/text");
        System.out.println(file.mkdir());//当前目录下接着创建目录(文件)
    }
}

输出结果

mkdirs()方法和mkdir()方法的区别,在当前目录下创建文件并且还可以接着创建

public class Test {
    public static void main(String[] args) throws IOException, InterruptedException {
        File file = new File("E:/IO/text/text2/text3");
        System.out.println(file.mkdirs());
    }
}

输出结果


文件内容的读写( 流对象)

标准库中,提供读写文件的流对象有很多,但是归纳为两个大类,其他流都继承这个两个大类

什么叫输入?什么叫输出?输入=>读,输出=>写

要站在cpu的角度考虑,一个数据保存到硬盘,对于cpu即是输出,一个数据从硬盘读到cpu,对于cpu即是输入

字符流(文本文件)

本质针对字节流进一步封装字符流能帮我们把文件中 几个相邻的字节 转换成 一个字符。相当于完成了一个自动查字符集表,每次读/写最小单位为"字符"(1个字符对应多个字节),1个字符范围是0-65535至于1个字符对应几个字节,看字符集是哪种,例如GBK一个中文字符对应两个字节,UTF8一个中文字符对应三个字节,提供了两个父类,Reader和Writer,接下来演示使用

Reader类

创建Reader对象的过程,就相当于打开文件的过程

read方法有三个参数的版本和无参的版本,并且返回值为int类型

为什么read方法返回类型为int?

0-65535这个范围是一个无符号char能表示的范围,一个字符对应两个字节。在java中如果是使用char类型的时候,使用Unicode进行编码的。使用String类型的时候则自动的把每个字符从Unicode编码转为UTF8编码。例如一个char[ ] c数组包含的每个字符固定使用Unicode进行编码。但是使用字符数组构造成String,例如String[ ] s=new String(c),此时自动的把每个字符转成UTF8编码,使用s.charAt(c),又会把UTF8编码的数据转换成Unicode。一个汉字,Unicode表示2个字节,UTF8表示3个字节。多个Unicode放到一起,难以区分哪到哪是一个完整的字符,UTF8可以做到就是针对连续多个字符传输的时候一种改进

总结按字节处理的时候采用Unicode编码,按字符串处理的时候采用UTF8编码

read()方法无参数,一次读取一个字符

public class Test {
    public static void main(String[] args) throws IOException, InterruptedException {
        try (Reader reader = new FileReader("E:/IO/text.txt")) {
            int read = reader.read();
            if (read == -1) {
                return;
            }
            char c = (char) read;
            System.out.print(c);
        }
    }
}

输出结果


read方法有参数一个字符数组,这个数组是空的字符数组,你把这个数组交给read方法,它把读到的填入这个数组里去,然后交给你。这个能一次读取多个字符

public class Test {
    public static void main(String[] args) throws IOException, InterruptedException {
        try (Reader reader = new FileReader("E:/IO/text.txt")) {
            char[] ch = new char[11];
            int read = reader.read(ch);
            System.out.println("读到的个数:" + read);
            while (true) {
                for (char c : ch) {
                    System.out.print(c);
                }
                break;
            }
        }
    }
}

输出结果,有个注意点我这边使用了try-Source关闭字符流防止文件资源泄露!!!

Writer类

和上面的差不多一个是读文件,一个则是写文件,有些注意的地方下面讲解

writer方法,把你要写的内容写入文件中,注意一下会把原先的内容覆盖掉,要是不想的话需要在构造方法中手动设置true这样就不会了

public class Test {
    public static void main(String[] args) {
        try (Writer writer = new FileWriter("E:/IO/text.txt")) {
            writer.write("我是字符流的Writer");
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}

基本流程:

1.先打开文件(构造方法)

2.读文件(Read)/写文件(Writer)

3.关闭文件(close)!!!


字节流(二进制文件)

每次读/写最小单位为"字节"(8bit)最少1字节,提供了两个父类,InputStream和OuputStream

InputStream类

和字符流的Reader差不多,只是这里是字节表示,1个字节范围是0-255,一般字节我们习惯使用16进制表示1个字节表示8个比特位,也就是两个16进制数字,bit就是位,也叫比特位,是计算机表示数据最小的单位。1个字节8bit,1byte=8bit。1byte就是1B,位就是bit也是b,1B=8b

public class Test {
    public static void main(String[] args) {
        try (InputStream inputStream = new FileInputStream("E:/IO/text.txt")) {
            byte[] s = new byte[6];
            int read = inputStream.read(s);
            System.out.println("读取到的个数:" + read);
            for (int i = 0; i < s.length; i++) {
                System.out.printf("%x\n", s[i]);
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}

输出结果,使用16进制输出

去确认一下对不对

outputStream类

和字符流的Writer差不多,构造方法不设置true会覆盖掉原来的内容

下面是代码演示,注意一下我们这里将字符串转为字节写入,因为我们使用的是字节流

public class Test {
    public static void main(String[] args) {
        try (OutputStream outputStream = new FileOutputStream("E:/IO/text.txt")) {
            String s = "java之父";
            outputStream.write(s.getBytes());
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}

输出结果

字节流转为字符流

有下面这几种方法:

1.使用scanner搭配InputStream可以从文件中读取数据了

public class Test {
    public static void main(String[] args) {
        try (InputStream inputStream = new FileInputStream("E:/IO/text.txt");) {
            Scanner scanner = new Scanner(inputStream);
            String s = scanner.next();
            System.out.println(s);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}

输出结果

2.使用PrintWriter类把字节流转字符流,把内容写入指定路径文件中

public class Test {
    public static void main(String[] args) {
        try (OutputStream outputStream = new FileOutputStream("E:/IO/text.txt")) {
            PrintWriter printWriter = new PrintWriter(outputStream);
            printWriter.printf("高斯林");
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}

输出结果,会发现写入高斯林,没有内容显示

缓冲区(buffer)

"缓冲区"是内存空间的一部分,PrintWriter这样的类,进行写数据的时候,不一定直接写入硬盘,而是先把数据写到一个内存构成的"缓冲区",引入缓冲区也是为了提高效率,因为我们知道把数据写到内存中比写到硬盘中速度要快很多,所以我们先把数据写到内存中,等内存中存的差不多了再写到硬盘中,这样能提供效率的同时减少读写硬盘的次数

但是要注意如果还没来得及把缓冲区的数据写入到硬盘中,此时进程结束了,数据就会丢失,所以为了确保数据能写入硬盘中,在合适的时机使用flush方法,手动刷新缓冲区,这样就可以确保数据写入到硬盘中。在刚才的代码加入flush方法,这样就能确保数据从缓冲区写到硬盘中了

public class Test {
    public static void main(String[] args) {
        try (OutputStream outputStream = new FileOutputStream("E:/IO/text.txt")) {
            PrintWriter printWriter = new PrintWriter(outputStream);
            printWriter.printf("高斯林");
            printWriter.flush();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}

以上便是关于如何使用java代码去操作文件的内容,多用用就能掌握,我们下一章再见💕

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

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

相关文章

C语言-预处理详解

文章目录 &#x1f3af;引言&#x1f453;预处理详解1.预定义符号1.1 __FILE__1.2 __LINE__1.3 __DATE__1.4 __TIME__1.5 __STDC__ 2.#define定义常量2.1 定义数值常量2.2 定义字符串常量 3.#define中使用参数3.1**使用示例**3.2注意事项 4.宏替换的规则5.宏函数和函数的对比5.…

基于Netty的自研流系统缓存实现挑战: 内存碎片与OOM困境

01 前言 Kafka 作为流处理平台&#xff0c;在实时流计算和在线业务场景&#xff0c;追尾读追求端到端低延迟。在离线批处理和削峰填谷场景&#xff0c;数据冷读追求高吞吐。两个场景都需要很好的数据缓存设计来支撑&#xff0c;Apache Kafka 的数据存储在本地文件&#xff0c…

从零开始学习嵌入式----C语言框架梳理与后期规划

目录 一、环境搭建. 二、见解 三、C语言框架梳理 四、嵌入式学习规划流程图&#xff08;学习顺序可能有变&#xff09; 一、环境搭建. C语言是一门编程语言&#xff0c;在学习的时候要准备好环境。我个人比较喜欢用VS,具体怎么安装请百度。学习C语言的时候&#xff0c;切忌…

Qt:12.输入类控件(QSpinBox-整数值输入的小部件、QDateEdit、QTimeEdit、QDateTimeEdit- 日期和时间输入的控件)

目录 一、QSpinBox-整数值输入的小部件&#xff1a; 1.1QSpinBox介绍&#xff1a; 1.2属性介绍&#xff1a; 1.3通用属性介绍&#xff1a; 1.4信号介绍&#xff1a; 二、QDateEdit、QTimeEdit、QDateTimeEdit- 日期和时间输入的控件&#xff1a; 2.1QDateEdit、QTimeEdit…

一、YOLO V10安装、使用、训练大全

YOLO V10安装、使用、训练大全 一、下载官方源码二、配置conda环境三、安装YOLOV10依赖四、使用官方YOLO V10模型1.下载模型2.使用模型2.1 图片案例 五、制作数据集1.数据集目录结构2.标注工具2.1 安装标注工具2.2 运行标注工具2.3 设置自动保存2.4 切换yolo模式2.5 开始标注2.…

【C++ | 继承】C++的继承详解 及 例子源码演示

&#x1f601;博客主页&#x1f601;&#xff1a;&#x1f680;https://blog.csdn.net/wkd_007&#x1f680; &#x1f911;博客内容&#x1f911;&#xff1a;&#x1f36d;嵌入式开发、Linux、C语言、C、数据结构、音视频&#x1f36d; ⏰发布时间⏰&#xff1a; 本文未经允许…

C++视觉开发 七.模板匹配

模板匹配是一种基于图像处理的技术&#xff0c;用于在目标图像中寻找与给定模板图像最相似的部分。通过设定的模板&#xff0c;将目标图像与模板图像比较&#xff0c;计算其相似度&#xff0c;实现对目标图像的判断。 目录 一.手写数字识别 重要函数&#xff1a; 1.cv::glob…

Mac平台虚拟机 Parallels Desktop v19.4.1,支持M1/M2/M3芯片组

Parallels Desktop for Mac是功能强大灵活度高的虚拟化方案&#xff0c;无需重启即可在同一台电脑上随时访问Windows和Mac两个系统上的众多应用程序。从仅限于PC的游戏到生产力软件&#xff0c;Parallels Desktop都能帮您实现便捷使用。Parallels Desktop 是一款专业的Mac虚拟机…

虚拟机因断电进入./#状态解决办法

现象&#xff1a; 解决&#xff1a;先查看错误日志&#xff1a;journalctl -p err -b查看自己虚拟机中标黄部分的名字 之后运行&#xff1a;xfs_repair -v -L /dev/sda #这里sda用你自己标黄的 最后重启 reboot 即可。

ArcGIS的智慧与情怀

初识ArcGIS 在这个信息化的时代&#xff0c;ArcGIS如同一位智者&#xff0c;静静地伫立在地理信息系统的巅峰。初识它时&#xff0c;我仿佛走进了一片未知的领域&#xff0c;心中充满了好奇与期待。ArcGIS&#xff0c;这款专业的地理信息系统软件&#xff0c;凭借其强大的功能…

【k8s中安装rabbitmq】k8s中安装rabbitmq并搭建镜像集群-hostpath版

文章目录 简介一.条件及环境说明二.需求说明三.实现原理及说明四.详细步骤4.1.规划节点标签4.2.创建configmap配置4.3.创建三个statefulset和service headless配置4.4.创建service配置 五.安装完后的配置六.安装说明 简介 k8s集群中搭建rabbitmq集群服务一般都会用到pvc&#x…

传知代码-图神经网络长对话理解(论文复现)

代码以及视频讲解 本文所涉及所有资源均在传知代码平台可获取 概述 情感识别是人类对话理解的关键任务。随着多模态数据的概念&#xff0c;如语言、声音和面部表情&#xff0c;任务变得更加具有挑战性。作为典型解决方案&#xff0c;利用全局和局部上下文信息来预测对话中每…

2024世界人工智能大会:AI产品技术与未来趋势的深度解析

随着2024年世界人工智能大会&#xff08;WAIC 2024&#xff09;在上海的圆满落幕&#xff0c;我们见证了人工智能技术的又一次飞跃。本次大会以“以共商促共享&#xff0c;以善治促善智”为主题&#xff0c;汇聚了全球顶尖的智慧&#xff0c;共同探讨了AI技术的未来趋势和应用前…

妙笔生词智能写歌词软件:创新助力还是艺术之殇?

在音乐创作日益普及和多样化的当下&#xff0c;各种辅助工具层出不穷&#xff0c;妙笔生词智能写歌词软件便是其中之一。那么&#xff0c;它到底表现如何呢&#xff1f; 妙笔生词智能写歌词软件&#xff08;veve522&#xff09;的突出优点在于其便捷性和高效性。对于那些灵感稍…

JVM内存泄露的ThreadLocal详解

目录 一、为什么要有ThreadLocal 二、ThreadLocal的使用 三、实现解析 实现分析 具体实现 Hash冲突的解决 开放定址法 链地址法 再哈希法 建立公共溢出区 四、引发的内存泄漏分析 内存泄漏的现象 分析 总结 错误使用ThreadLocal导致线程不安全 一、为什么要有Thr…

Test-Time Adaptation via Conjugate Pseudo-labels--论文笔记

论文笔记 资料 1.代码地址 https://github.com/locuslab/tta_conjugate 2.论文地址 https://arxiv.org/abs/2207.09640 3.数据集地址 论文摘要的翻译 测试时间适应(TTA)指的是使神经网络适应分布变化&#xff0c;在测试时间仅访问来自新领域的未标记测试样本。以前的TT…

【pytorch24】Visdom可视化

TensorboardX pytorch有一个工具借鉴了tensorboard pip install tensorboardX 有查看变量的数值、监听曲线等功能 如何使用 新建SummaryWriter()实例 要把监听的数据&#xff0c;比如说要监听dummy_s1[0]&#xff08;y 坐标&#xff09;存放到data/scalar1中&#xff0c;…

普中51单片机:中断系统与寄存器解析(六)

文章目录 引言中断流程图中断优先级下降沿中断结构图中断相关寄存器IE中断允许寄存器&#xff08;可位寻址&#xff09;XICON辅助中断控制寄存器&#xff08;可位寻址&#xff09;TCON标志控制寄存器SCON串行口控制寄存器 中断号中断响应条件中断函数代码模板电路图开发板IO连接…

洁净车间的压缩空气质量如何检测(露点、水油、粒子、浮游菌)

通常一个空压机站的设备即为一个狭义的压缩空气系统&#xff0c;下图为一个典型的压缩空气系统流程图&#xff1a; 气源设备&#xff08;空气压缩机&#xff09;吸入大气&#xff0c;将自然状态下的空气压缩成为具有较高压力的压缩空气&#xff0c;经过净化设备除去压缩空气中的…

新手如何正确学习Python?分享我是如何2个月熟练掌握Python的!学习大纲+学习方式+学习资料 汇总!

前言 一直以来都有很多想学习Python的朋友们问我&#xff0c;学Python怎么学&#xff1f;爬虫和数据分析怎么学&#xff1f;web开发的学习路线能教教我吗&#xff1f; 我先告诉大家一个点&#xff0c;不管你是报了什么培训班&#xff0c;还是自己在通过各种渠道自学&#xff…