Java 文件IO

一、什么是文件IO

文件是一个广义的概念,操作系统将很多资源都抽象成文件,这篇文章讲解文件特指硬盘上的文件

在硬盘上存在很多文件和目录,它们以一种N叉树的结构存储

注意:文件夹也是一种文件,它是一种目录文件

二、路径

为了能定位到某个具体文件,需要引入路径,路径就是从根节点为起点,经过一些目录最终到达目标文件的"集合";路径分为绝对路径相对路径

1)绝对路径:

以盘符为开头的路径称为绝对路径,如:D:/program/qq/Bin/qq.exe

2)相对路径:

相对路径的起点可以是任意路径

这个是qq.exe的绝对路径:D:/program/qq/Bin/qq.exe

假如当前的基准是D:/program/qq/Bin,那相对路径可以写成:. /qq.exe. 表示当前位置

当前基准是D:/program/qq,相对路径可以写成:./Bin/qq.exe

当前基准是D:/program/qq/Bin/plugins,相对路径可以写成:. . /qq.exe(..表示返回上一级目录)

三、文件的分类

文件的分类有很多种,这里讲解一种和编写代码密切相关的:文本文件 vs 二进制文件

将文件从记事本打开:

左侧:文本文件;右侧:乱码→二进制文件

文本文件是给人看的,二进制文件是给程序看的

四、使用Java操作文件

1)针对文件系统操作,如:创建文件、删除文件、重命名文件、创建目录等

2)针对文件内容操作,如:读文件、写文件

4.1 针对文件系统

Java标准库提供了 File 类来表示一个文件实例,File 提供了一些构造方法和方法

构造方法描述

File (File parent,String child)

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

方法描述

String  getParent()    

返回File对象的父目录文件路径
String  getName()    返回FIle对象的纯文件名称
String  getPath()    返回File对象的文件路径
String  getAbsolutePath()    返回File对象的绝对路径
String  getCanonicalPath()    返回File对象的修饰过的绝对路径

方法演示:

File file = new File("./test.txt"); //.代表当前项目的路径System.out.println("file.getParent(): "+ file.getParent());System.out.println("file.getName(): "+ file.getName());System.out.println("file.getPath() :"+ file.getPath());System.out.println("file.getAbsolutePath(): "+ file.getAbsolutePath());System.out.println("file.getCanonicalPath(): "+ file.getCanonicalPath());

结果演示:


方法描述
boolean  exists()    判断File对象描述的⽂件是否真实存在
boolean  isDirectory()  判断File对象代表的⽂件是否是⼀个⽬录
boolean  isFile()  判断File对象代表的⽂件是否是⼀个普通⽂件
boolean  createNewFile()    根据File对象,⾃动创建⼀个空⽂件。成功创建后返回true

方法演示:

File file = new File("./test.txt");
// 此时还没有创建文件, file只是一个File实例System.out.println(file.exists()); //falseSystem.out.println(file.isFile()); //falseSystem.out.println(file.isDirectory()); //false
File file = new File("./test.txt");
// 此时创建了文件
file.createNewFile();System.out.println(file.exists()); //trueSystem.out.println(file.isFile()); //trueSystem.out.println(file.isDirectory()); //false

方法

描述
boolean  delete()    根据File对象,删除该⽂件。成功删除后返回true
void  deleteOnExit()    根据File对象,标注⽂件将被删除,删除动作会到JVM运⾏结束时(进程结束)才会进行
String[]  list()    返回File对象代表的⽬录下的所有⽂件名
File[]  listFiles()    返回File对象代表的⽬录下的所有⽂件,以File对象表⽰
boolean  mkdir()  创建File对象代表的⽬录,只能创建一级目录
boolean  mkdirs()    创建File对象代表的⽬录,可以创建多级目录
public static void main(String[] args) {File f = new File("./testDir");f.mkdir();System.out.println(f.isDirectory());
}


方法描述
boolean  renameTo(File dest)进行文件改名,也可以视为我们平时的剪切、粘贴操作
boolean  canRead()判断用户是否对⽂件有可读权限
boolean  canWrite()判断用户是否对⽂件有可写权限
public static void main(String[] args) {File f = new File("./testDir/test2.txt");File file = new File("./test.txt");file.renameTo(f); //将原本路径下的文件修改为新路径下的新名字的文件
}

4.2 针对文件内容

Java中通过流这样的一组类,进行文件内容的操作

字节流:以字节为单位读写数据(二进制文件) → InputStream、OutPutStream

字符流:以字符为单位读写数据(文本文件)→ Reader、Writer

4.2.1 InputStream

InputStream是一个抽象类,不能实例化,但标准库已经提供好了子类

InputStream inputStream = new FileInputStream("./testDir/test2.txt");

这里构造方法填写参数:

  1. 填写字符串表示的文件路径(绝对/相对均可)
  2. 填写File对象

这行代码就会通过构造方法打开一个文件,如果打开文件成功,就可以进行后续读取操作了

1)int read()

一次读取一个字节,将读取到的内容返回

此处一次读取一个字节,为什么返回值类型不是byte,而是int:

read()方法,如果返回值类型是byte,byte的取值范围为-128到127,但是需要一种机制表示输入流结束,这里通过返回-1表示流结束,但是-1在-128到127属于有效值,所以要改为int扩大取值范围,让0到255表示有效值,-1表示流结束

代码案例:

事先在test2.txt里面写上hello

public static void main(String[] args) throws IOException {InputStream inputStream = new FileInputStream("./testDir/test2.txt");while (true) {int b = inputStream.read();if (b == -1) {break;}System.out.printf("0x%x ", b);}
}

将16进制转化为10进制,正好对应ASCIIdh、e、l、l、o

2)int read ( byte[ ]  b )

将读到的数据填写到byte数组中,返回值代表实际读取了多少个字节,返回-1代表读完了

代码案例:

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

每次读完都会将数据存放在b中,如果文件数据过多,每次读取都会填满数组,然后循环多次

3)int  read ( byte[ ]  b,  int  off,  int  len )

读取文件中数据并填充数组的一部分,从 offset 开始,填充 len 这么长

4.2.2 关闭文件

打开文件的时候,操作系统内核会向该进程中的PCB结构体中,给文件描述符表里添加一个元素,这个元素表示当前打开的文件的各种信息(文件描述符表相当于一个顺序表,但不能扩容),当使用close关闭文件时,文件描述符表里对应的元素就会被释放掉

如果文件只开不关,文件描述符表就会被占满,一旦占满,再次打开文件,就会打开失败

我们刚刚写的程序,没有关闭文件好像没什么问题,这是因为代码很快就执行完了,进程也就结束了,进程一结束,pcb就会被释放掉,就没有什么机会将文件描述表占满,

打开文件和关闭文件之间会有一系列的操作,有的操作可能会return或抛出异常,导致文件没有及时关闭,和之前ReentrantLock类似:将解锁操作写到finally里;这里关闭文件也可以写到finally里

除此之外还有一种方法:try  with  resource

将流对象的创建写到 try ( ) 中,代码执行出了 try { } 后,就会自动调用关闭文件的操作,注意,写进 try ( ) 中的流对象的类必须实现了 Closeable 接口

try (InputStream inputStream = new FileInputStream("D:/test.txt")) {byte[] b = new byte[1024];int n = inputStream.read(b);for (int i = 0; i < n; i++) {System.out.printf("0x%x ", b[n]);}
}

4.2.3 OutputStream

方法描述
void  write ( int  b )一次写一个字节
void  write ( byte[ ]  b )一次写若干个字节,把数组b里的所有字节都写入文件中
void  write ( byte[ ]  b,  int  off,  int  len )一次写若干个字节,从b数组的off下标开始写,写len个字节
//OutputStream 为抽象类,使用子类 FileOutputStream 实例化
OutputStream out = new FileOutputStream("./testDir/test2.txt");
//连续写3个 a
out.write(97);
out.write(97);
out.write(97);

按照写方式打开文件时,会把文件原有的内容清空(不是write清空的,而是打开文件时清空的)可以使用追加写

新数据会在原数据的末尾:

4.2.4 Reader

方法描述
int  read  ( )一次读取一个字符,返回-1表示读取结束
int  read  ( char[ ]  cbuf )读取若干个字符到cbuf数组中,返回-1表示读取结束

事先在test2.txt中写上:你好世界

public static void main(String[] args) {//Reader为抽象类,使用子类 FileReader 实例化try (Reader reader = new FileReader("./testDir/test2.txt")) {while (true) {int b = reader.read(); //一次读取一个字符if (b == -1) {break;}char ch = (char)b;System.out.println(ch);}} catch (IOException e) {throw new RuntimeException(e);}
}

  • 问题:读出来的内容是中文,一个中文字符占3个字节,但Java中char类型占2个字节,为什么可以读取成功?
  • 答:虽然文件中原始数据是3个字节一个字符,read操作读取的时候,能够识别文件是utf-8格式,读的是3个字节,返回成一个char的时候,会将utf-8转成unicode,这样一个字符就占2个字节

4.2.5 Writer

方法描述
void  write( int  c )一次写一个字符
void  write( char[ ]  cbuf )将数组 cbuf 中的字符写入文件
void  write( String  str )将字符串 str 写入字符
public static void main(String[] args) {try (Writer writer = new FileWriter("./testDir/test2.txt", true)) {writer.write('0');char[] c = {'\n', '数', '组'};writer.write(c);String str = "\n字符串";writer.write(str);} catch (IOException e) {e.printStackTrace();}
}


🙉本篇文章到此结束

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

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

相关文章

Rnnoise和SpeexDsp两种降噪方式有什么区别?

在蒙以CourseMaker 7.0软件中&#xff0c;增加了两种降噪模式&#xff0c;一种是Rnnoise&#xff0c;一种是SpeexDsp&#xff0c;这两种降噪模式有什么区别呢&#xff1f; Rnnoise 基于神经网络。当噪声与 rnnoise 的模型训练的噪声匹配时&#xff0c;它的效果非常好。比如说&…

搭建Discuz论坛

lnmp l&#xff1a;linux操作系统 n&#xff1a;nginx前端页面 m&#xff1a;mysql数据库&#xff0c;账号密码等等都是保存在这个数据库里面 p&#xff1a;php------nginx擅长处理的是静态页面&#xff0c;页面登录账户&#xff0c;需要请求到数据库&#xff0c;通过php把动态…

鸿蒙分享(四):弹窗简单封装

代码仓库&#xff1a;https://gitee.com/linguanzhong/share_harmonyos 鸿蒙api:12 引用的harmony-utils地址&#xff1a;OpenHarmony三方库中心仓 引用的harmony-dialog地址&#xff1a;OpenHarmony三方库中心仓 引用的loading-dialog地址OpenHarmony三方库中心仓 import…

厦门凯酷全科技有限公司抖音电商服务的卓越典范

在短视频和直播带货迅速崛起的时代&#xff0c;厦门凯酷全科技有限公司&#xff08;以下简称“凯酷全科技”&#xff09;以其专业的服务、创新的精神以及对市场的深刻理解&#xff0c;在抖音电商领域中脱颖而出&#xff0c;成为众多品牌商家信赖的选择。本文将深入探讨凯酷全科…

扫二维码进小程序的指定页面

草料二维码解码器 微信开发者工具 获取二维码解码的参数->是否登陆->跳转 options.q onLoad: function (options) {// console.log("options",options.q)if (options && options.q) {// 解码二维码携带的链接信息let qrUrl decodeURIComponent(optio…

MitelMiCollab 身份绕过导致任意文件读取漏洞复现(CVE-2024-41713)

0x01 产品描述: Mitel MiCollab 是一个企业协作平台,它将各种通信工具整合到一个应用程序中,提供语音和视频通话、消息传递、状态信息、音频会议、移动支持和团队协作功能。0x02 漏洞描述: Mitel MiCollab 的 NuPoint 统一消息 (NPM) 组件中存在身份验证绕过漏洞,由于输入…

电子商务人工智能指南 6/6 - 人工智能生成的产品图像

介绍 81% 的零售业高管表示&#xff0c; AI 至少在其组织中发挥了中等至完全的作用。然而&#xff0c;78% 的受访零售业高管表示&#xff0c;很难跟上不断发展的 AI 格局。 近年来&#xff0c;电子商务团队加快了适应新客户偏好和创造卓越数字购物体验的需求。采用 AI 不再是一…

如何在 Ubuntu 上安装开源监控工具 Uptime Kuma

简介 Uptime Kuma&#xff08;或简称 Kuma&#xff09;是一个开源监控工具&#xff0c;用于监控 HTTP、HTTPS、DNS 等协议的服务。Uptime Kuma 提供多种功能&#xff0c;如多语言支持、多个状态页面、代理支持等。 接下来&#xff0c;我将一步一步教大家如何进行安装和部署&am…

国城杯2024——Curve

相关知识链接&#xff1a;https://tangcuxiaojikuai.xyz/post/187210a7.html #sagemath from Crypto.Util.number import *def add(P, Q):(x1, y1) P(x2, y2) Qx3 (x1*y2 y1*x2) * inverse(1 d*x1*x2*y1*y2, p) % py3 (y1*y2 - a*x1*x2) * inverse(1 - d*x1*x2*y1*y2, p…

第三部分:进阶概念 8.事件处理 --[JavaScript 新手村:开启编程之旅的第一步]

JavaScript 事件处理是 Web 开发中不可或缺的一部分&#xff0c;它允许开发者响应用户的交互行为&#xff08;如点击、键盘输入等&#xff09;或浏览器的行为&#xff08;如页面加载完成&#xff09;。通过事件处理&#xff0c;我们可以使网页更加动态和互动。以下是关于 JavaS…

STM32WB55 FUS烧录

FUS固件下载 Firmware Update Service&#xff08;FUS&#xff09;是一种用于在STM32WB微控制器上更新固件的功能。FUS下载是指通过FUS服务进行固件更新的过程。通过FUS下载&#xff0c;您可以通过无线方式将新的固件加载到STM32WB设备中&#xff0c;而无需使用传统的有线编程方…

BERT模型的实现

本文用 pytorch 实现一个BERT模型。 食用方法&#xff1a; 直接下载完整实现&#xff0c; 在自己本地跑一遍&#xff0c;保证不报错。先完成数据预处理阶段&#xff08;1-4&#xff09;的代码阅读&#xff0c;然后按照如下关键点的描述完成代码的实现。自己看着代码手写后续部…

Qt之第三方库‌QXlsx使用(三)

Qt开发 系列文章 - QXlsx&#xff08;三&#xff09; 目录 前言 一、Qt开源库 二、QXlsx 1.QXlsx介绍 2.QXlsx下载 3.QXlsx移植 4.修改项目文件.pro 三、使用技巧 1.添加头文件 2.写入数据 3.读出数据 总结 前言 Qt第三方控件库是指非Qt官方提供的、用于扩展Qt应用…

框架篇面试

一、Spring框架中的单例bean的安全性 Spring框架中有一个Scope注解&#xff0c;默认的值就是singleton&#xff0c;单例的&#xff1b;因为一般在spring的bean中注入的都是无状态的对象&#xff0c;所以没有线程安全问题。但是如果在bean中定义了可修改的成员变量&#xff0c;…

OpenAI 发布 o1 LLM,推出 ChatGPT Pro

OpenAI正式发布了专为复杂推理而构建的 OpenAI o1大型语言模型(LLM)。 该公司还推出了 ChatGPT Pro&#xff0c;这是一项每月 200 美元的套餐&#xff0c;包括无限制访问 OpenAI o1、o1-mini、GPT-4o 和高级语音对话。 OpenAI o1 从 9 月 12 日起在 ChatGPT 中推出预览版&…

【Linux】文件描述符fd

1.前置预备 文件 内容 属性访问文件之前&#xff0c;都必须先打开他 #include<stdio.h> int main() { FILE* fpfopen("log.txt","w"); if(fpNULL) { perror("fopen"); return 1; } fclose(fp); return 0…

字节高频算法面试题:小于 n 的最大数

问题描述&#xff08;感觉n的位数需要大于等于2&#xff0c;因为n的位数1的话会有点问题&#xff0c;“且无重复”是指nums中存在重复&#xff0c;但是最后返回的小于n最大数是可以重复使用nums中的元素的&#xff09;&#xff1a; 思路&#xff1a; 先对nums倒序排序 暴力回…

李飞飞首个“空间智能”模型发布:一张图,生成一个3D世界 | LeetTalk Daily

“LeetTalk Daily”&#xff0c;每日科技前沿&#xff0c;由LeetTools AI精心筛选&#xff0c;为您带来最新鲜、最具洞察力的科技新闻。 在人工智能技术迅速发展的背景下&#xff0c;李飞飞创立的世界实验室于近期发布了首个“空间智能”模型&#xff0c;这一创新成果引发了3D生…

Cursor+Devbox AI开发快速入门

1. 前言 今天无意间了解到 Cursor 和 Devbox 两大开发神器,初步尝试以后发现确实能够大幅度提升开发效率,特此想要整理成博客以供大家快速入门. 简单理解 Cursor 就是一款结合AI大模型的代码编辑器,你可以将自己的思路告诉AI,剩下的目录结构的搭建以及项目代码的实现均由AI帮…

机器学习--绪论

开启这一系列文章的初衷&#xff0c;是希望搭建一座通向机器学习世界的桥梁&#xff0c;为有志于探索这一领域的读者提供系统性指引和实践经验分享。随着人工智能和大数据技术的迅猛发展&#xff0c;机器学习已成为推动技术创新和社会变革的重要驱动力。从智能推荐系统到自然语…