文件操作和IO流

  前言👀~

上一章我们介绍了多线程进阶的相关内容,今天来介绍使用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.mzph.cn/diannao/44095.shtml

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

相关文章

leetcode--恢复二叉搜索树

leetcode地址&#xff1a;恢复二叉搜索树 给你二叉搜索树的根节点 root &#xff0c;该树中的 恰好 两个节点的值被错误地交换。请在不改变其结构的情况下&#xff0c;恢复这棵树 。 示例 1&#xff1a; 输入&#xff1a;root [1,3,null,null,2] 输出&#xff1a;[3,1,null…

AirPods Pro新功能前瞻:iOS 18的五大创新亮点

随着科技的不断进步&#xff0c;苹果公司一直在探索如何通过创新提升用户体验。iOS 18的推出&#xff0c;不仅仅是iPhone的一次系统更新&#xff0c;更是苹果生态链中重要一环——AirPods Pro的一次重大升级。 据悉&#xff0c;iOS 18将为AirPods Pro带来五项新功能&#xff0…

设计模式探索:观察者模式

1. 观察者模式 1.1 什么是观察者模式 观察者模式用于建立一种对象与对象之间的依赖关系&#xff0c;当一个对象发生改变时将自动通知其他对象&#xff0c;其他对象会相应地作出反应。 在观察者模式中有如下角色&#xff1a; Subject&#xff08;抽象主题/被观察者&#xf…

详细分析@FunctionalInterface的基本知识(附Demo)

目录 前言1. 基本知识2. Demo 前言 Java的基本知识推荐阅读&#xff1a; java框架 零基础从入门到精通的学习路线 附开源项目面经等&#xff08;超全&#xff09;Spring框架从入门到学精&#xff08;全&#xff09; 1. 基本知识 FunctionalInterface 是 Java 8 引入的一个注…

外卖商城平台小程序的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;用户管理&#xff0c;商家管理&#xff0c;骑手管理&#xff0c;商品类型管理&#xff0c;商品信息管理&#xff0c;订单信息管理 微信端账号功能包括&#xff1a;系统首页&#xff0c;商品信息&#…

模板初阶详解

目录 泛型编程函数模板函数模板概念函数模板格式函数模板的原理函数模板的实例化隐式实例化强制类型转换的疑惑 显式实例化 模板参数的匹配原则 类模板类模板的定义格式类模板的实例化 感谢各位大佬对我的支持,如果我的文章对你有用,欢迎点击以下链接 &#x1f412;&#x1f41…

微信小程序接口wx.getLocation违规导致封禁解决办法

1、找到站内信的这个封禁的通知&#xff08;功能封禁的通知&#xff0c;而不是处理警告的通知&#xff09; 2、点击通知会有申诉链接&#xff0c;点开申诉链接 申诉原因可参考下面的内容&#xff1a; 1.小程序哪些板块已除去收集地理位置、2.哪些板块需要收集地理位置、3.详细…

WindowsMac共享文件夹设置

共享文件夹设置 共享文件夹设置Windows系统设置步骤一&#xff1a;设置共享文件夹步骤二: 访问共享文件夹 Mac系统中设置共享文件夹步骤一&#xff1a;设置共享文件夹步骤二&#xff1a;访问共享文件夹 小贴士结论 共享文件夹设置 有时需要在多台电脑之间共享文件夹&#xff0…

4.MkDocs样式

学习 Admonitions(警告) - Material for MkDocs (wdk-docs.github.io) 提示 - Material for MkDocs 中文文档 (llango.com) Buttons(按钮) - Material for MkDocs (wdk-docs.github.io) 建议去看这些网站&#xff0c;更为详细。 常用功能 便利贴 ​​ 开启 markdown_ex…

Gemma2——Google 新开源大型语言模型完整应用指南

0.引言 Gemma 2以前代产品为基础&#xff0c;提供增强的性能和效率&#xff0c;以及一系列创新功能&#xff0c;使其在研究和实际应用中都具有特别的吸引力。Gemma 2 的与众不同之处在于&#xff0c;它能够提供与更大的专有模型相当的性能&#xff0c;但其软件包专为更广泛的可…

hdfs大规模数据存储底层原理详解(第31天)

系列文章目录 一、HDFS设计原理 二、HDFS系统架构 三、HDFS关键技术 四、HDFS应用实例 五、解决HDFS不能处理小文件详解问题 文章目录 系列文章目录前言一、设计原理二、系统架构三、关键技术四、应用实例五、解决HDFS不能处理小文件详解问题1. 合并小文件2. 优化Hive配置3. 使…

DDR3 SO-DIMM 内存条硬件总结(一)

最近在使用fpga读写DDR3&#xff0c;板子上的DDR3有两种形式与fpga相连&#xff0c;一种是直接用ddr3内存颗粒&#xff0c;另一种是通过内存条的形式与fpga相连。这里我们正好记录下和ddr3相关的知识&#xff0c;先从DDR3 SO-DIMM 内存条开始。 1.先看内存条的版本 从JEDEC下载…

Mysql练习题目【7月10日更新】

七、Mysql练习题目 https://zhuanlan.zhihu.com/p/38354000 1. 创建表 创建学生表 mysql> create table if not exists student(-> student_id varchar(255) not null,-> student_name varchar(255) not null,-> birthday date not null,-> gender varchar(…

前端面试题33(实时消息传输)

前端实时传输协议主要用于实现实时数据交换&#xff0c;特别是在Web应用中&#xff0c;它们让开发者能够构建具有实时功能的应用&#xff0c;如聊天、在线协作、游戏等。以下是几种常见的前端实时传输协议的讲解&#xff1a; 1. Short Polling (短轮询) 原理&#xff1a;客户…

【1】A-Frame整体介绍

1.A-Frame是什么&#xff1f; A-Frame 是一个用于构建虚拟现实 (VR) 体验的 Web 框架。 A-Frame 基于 HTML 之上&#xff0c;因此上手简单。但 A-Frame 不仅仅是 3D 场景图或标记语言&#xff1b;它还是一种标记语言。其核心是一个强大的实体组件框架&#xff0c;为 Three.js …

Golang | Leetcode Golang题解之第226题翻转二叉树

题目&#xff1a; 题解&#xff1a; func invertTree(root *TreeNode) *TreeNode {if root nil {return nil}left : invertTree(root.Left)right : invertTree(root.Right)root.Left rightroot.Right leftreturn root }

uniapp+vue3嵌入Markdown格式

使用的库是towxml 第一步&#xff1a;下载源文件&#xff0c;那么可以git clone&#xff0c;也可以直接下载压缩包 git clone https://github.com/sbfkcel/towxml.git 第二步&#xff1a;设置文件夹内的config.js&#xff0c;可以选择自己需要的格式 第三步&#xff1a;安装…

UML 2.5图的分类

新书速览|《UML 2.5基础、建模与设计实践》新书速览|《UML 2.5基础、建模与设计实践 UML 2.5在UML 2.4.1的基础上进行了结构性的调整&#xff0c;简化和重新组织了 UML规范文档。UML规范被重新编写&#xff0c;使其“更易于阅读”&#xff0c;并且“尽可能减少前向引用”。 U…

LLM应用构建前的非结构化数据处理(三)文档表格的提取

1.学习内容 本节次学习内容来自于吴恩达老师的Preprocessing Unstructured Data for LLM Applications课程&#xff0c;因涉及到非结构化数据的相关处理&#xff0c;遂做学习整理。 本节主要学习pdf中的表格数据处理 2.环境准备 和之前一样&#xff0c;可以参考LLM应用构建前…

金蝶部署常见问题解决

金蝶部署常见问题解决 金蝶版本&#xff1a; Apusic Application Server Enterprise Edition 9.0 SP8 kbc build 202312041121 报错信息&#xff1a; 与金蝶官方人员沟通&#xff0c;发现lib包版本太低&#xff0c;升级后可正常使用。替换lib包后重启服务。 下载lib: 链接: …