Java【文件和IO】File 类, 字节IO流的使用

news2024/9/28 21:27:07

文章目录

  • 前言
  • 一、File 类
    • 1, 构造方法
    • 2, 成员方法
  • 二、字节流输入输出
    • 1, 字节流输入 InputStream
      • 1.1, 每次输入一个字节
      • 1.2, 每次输入多个字节
    • 2, 字节流输出 OutputStream
      • 2.1, 每次输出一个字节
      • 2.2, 每次输出多个字节
  • 总结


前言

各位读者好, 我是小陈, 这是我的个人主页, 希望我的专栏能够帮助到你:
📕 JavaSE基础: 基础语法, 类和对象, 封装继承多态, 接口, 综合小练习图书管理系统等
📗 Java数据结构: 顺序表, 链表, 堆, 二叉树, 二叉搜索树, 哈希表等
📘 JavaEE初阶: 多线程, 网络编程, TCP/IP协议, HTTP协议, Tomcat, Servlet, Linux, JVM等(正在持续更新)

之前几篇文章陆续介绍了 Java 多线程的相关知识, 本篇继续介绍文件操作和 IO 流相关的基础内容

文件, 狭义上讲, 电脑中 C 盘 D 盘中的文件, 广义上讲, 很多操作系统为了实现接口的统一性,将所有的 IO 设备都抽象成了文件
IO 是指 : Input输入 和 Output输出
IO 设备就是 : 可以把数据输入到计算机, 或者把计算机中的数据输出的外部设备


提示:是正在努力进步的小菜鸟一只,如有大佬发现文章欠佳之处欢迎批评指点~ 废话不多说,直接上干货!

识狭义上的文件 : 针对硬盘这种持久化存储的 I/O 设备,当我们想要进行数据保存时,往往不是保存成一个整体,而是独立成一个个的单位进行保存,这个独立的单位就被抽象成文件的概念,就类似办公桌上的一份份真实的文件一般。

狭义上的文件包括文件夹和普通文件, 例如下图 : D 盘就是一个文件夹, 打开之后包含若干个文件夹和普通文件. 这些文件夹再打开可能还包含若干文件夹和普通文件
在这里插入图片描述
可以发现, 文件的存储结构实际上就是树形结构, 文件夹都是"非叶子节点", 普通文件都是"叶子节点" , 文件夹的专业术语是目录


一、File 类

Java 标准库封装了一个 File 类来操作文件, 如果把电脑上的文件当作电视机, File 类的对象就是遥控器, 通过路径把 File 对象实例出来(于遥控器和电视机连接上了), 就可以利用 File 对象(遥控器)来操作文件(电视机)

不完全准确的类比, 但是意思差不多

注意 : 实例化出来 File 对象, 并不代表电脑上就真实存在这个文件

1, 构造方法

        File file = new File("D:\\Program Files\\Tencent\\QQ\\Bin\\test.txt");

构造方法的参数是该目标文件的路径, 这个路径可以是绝对路径, 也可以是相对路径, 都是字符串

绝对路径 : 从盘符开始, 到目标文件的完整路径
相对路径 : 从某个目录(工作目录)开始, 到目标文件的路径, 相对路径中, "."表示当前目录, ".."表示上一级目录

如果以当前 Java 项目所在的目录为工作目录, 在这个目录下创建test.txt这个文件 相对路径就可以表示成 : ./test.txt
以相对路径的方式创建 file 对象的代码: File file = new File(“./test.txt”);


2, 成员方法

返回值方法名说明
StringgetParent()返回 File 对象的父目录文件路径
StringgetName()返回 FIle 对象的纯文件名称
StringgetPath()返回 File 对象的文件路径
StringgetAbsolutePath()返回 File 对象的绝对路径
StringgetCanonicalPath()返回 File 对象的修饰过的绝对路径
        System.out.println(file.getName() + " --> 文件名");
        System.out.println(file.getParent() + " --> 父目录文件路径");
        System.out.println(file.getPath() + " --> 路径");
        System.out.println(file.getAbsolutePath() + " --> 绝对路径");
        System.out.println(file.getCanonicalFile() + " --> 修饰后的绝对路径");

运行结果 :
在这里插入图片描述
下面三行输出看起来没有什么区别, 但是如果把构造方法里的路径换成相对路径, 区别就很明显了, 各位读者可以自行尝试


返回值方法名说明
booleanexists()判断 File 对象描述的文件是否真实存在
booleanisDirectory()判断 File 对象代表的文件是否是一个目录
booleanisFile()判断 File 对象代表的文件是否是一个普通文件
booleancreateNewFile()根据 File 对象,自动创建一个空文件。成功创建后返回 true
booleandelete()根据 File 对象,删除该文件。成功删除后返回 true
voiddeleteOnExit()根据 File 对象,标注文件将被删除,删除动作会到 JVM 运行结束时才会进行
        System.out.println(file.exists() + " --> 是否存在");
        System.out.println(file.createNewFile() + " --> 是否成功创建(第一次)");
        System.out.println(file.createNewFile() + " --> 是否成功创建(第二次)");
        
        System.out.println(file.isDirectory() + " --> 是否为目录");
        System.out.println(file.isFile() + " --> 是否为普通文件");

        System.out.println(file.delete() + " --> 是否成功删除(第一次)");
        System.out.println(file.delete() + " --> 是否成功删除(第二次)");

运行结果 :
在这里插入图片描述


下面是创建目录的方法

返回值方法名说明
booleanmkdir()创建 File 对象代表的目录
        File dir = new File("D:\\Program Files\\Tencent\\QQ\\Bin\\test");

        System.out.println(dir.exists() + " --> 是否存在");
        System.out.println(dir.isDirectory() + " --> 是否为目录");
        System.out.println(dir.isFile() + " --> 是否为普通文件");

        System.out.println(dir.mkdir() + " --> 是否为成功创建");
        System.out.println(dir.delete() + " --> 是否为成功删除");

        System.out.println(dir.exists() + " --> 是否存在");

运行结果 :
在这里插入图片描述


下面是创建多级目录的方法

返回值方法名说明
booleanmkdirs()创建 File 对象代表的目录,如果必要,会创建中间目录
        File dir = new File("D:\\Program Files\\Tencent\\QQ\\Bin\\test2/aaa/bbb");

由于本机没有test2 和 aaa 这两个文件, 这个方法会创建出来从 test2 到 bbb 这三层目录, 我们可以用以下两个方法观察

返回值方法名说明
String[]list()返回 File 对象代表的目录下的所有文件名
File[]listFiles()返回 File 对象代表的目录下的所有文件,以 File 对象表示
        File dir = new File("D:\\Program Files\\Tencent\\QQ\\Bin\\test2/aaa/bbb");
        System.out.println(dir.mkdirs() + " --> 是否为成功创建");

        File dir2 = new File("D:\\Program Files\\Tencent\\QQ\\Bin\\test2");
        String[] results1 = dir2.list();
        File[] results2 = dir2.listFiles();
        System.out.println(Arrays.toString(results1));
        System.out.println(Arrays.toString(results2));

运行结果 :
在这里插入图片描述


以上就是 File 类的常用方法介绍, 下面介绍字节流的 IO 操作

  • 明确"流"的概念
    “流”, 可以联想到"水流", 把水龙头打开就会有水流出来, 并且可以控制流出来的水的快慢
    水流的最小单位是水滴, 而字节流 IO 的最小单位就是一个字节

  • 明确"输入"和"输出"的方向
    输入输出都是以 CPU 的视角来看的, CPU 运行时是从内存中读取数据, 而文件在硬盘(外存)上,
    文件输入, 是硬盘 --> 内存 --> CPU , 数据流入到 CPU(读取文件中的数据)
    文件输出, 是 CPU --> 内存 --> 硬盘, 数据从 CPU 流出(把数据写入到文件)

  • 明确对应的类
    字节流 IO 操作使用的类是 : InputStream 和 OutputStream

二、字节流输入输出

1, 字节流输入 InputStream

1.1, 每次输入一个字节

InputStream 这个类是一个抽象类, 不能被直接实例化, 应该实例化它的子类

文件只是 IO 设备的其中一种, 还有其他 IO 设备(比如网卡…), 所以针对文件的 IO 操作的类是 FileInputStream, 需要在构造方法中指定路径来表示操作的具体文件是哪个(或者是 File 对象)

注意 :
实例化出来对象之后就相当于文件被打开, (产生了文件描述符), 使用完文件之后需要调用 close 方法关闭文件, 否则可能会产生文件资源泄露的严重bug

由于字节流字符流的 IO 操作的类都继承了 Closeable 这个接口, 所以有了一种新的语法 :

        try(InputStream inputStream = new FileInputStream("D:/hello.txt")) {
            
            }
        }

try(实例化对象) { }, 当大括号中的代码执行完后, 就会自动的调用 close 方法

调用 inputStream.read() 就可以读取一个字节的数据, 如果读到文件末尾, 返回值为 -1, 我们不知道文件中有多少字节的数据, 所以利用 while 循环 :

        // 输入流  从硬盘读到内存
        try(InputStream inputStream = new FileInputStream("D:/hello.txt")) {
            while(true) {
                int ret = inputStream.read();
                if(ret == -1) {
                	// 说明读完了
                    break;
                }
                System.out.println(ret);
            }
        }

在这里插入图片描述
如果文件中的数据是字母和标点符号, 根据数字查询 ASCII 码表即可, 如果是汉字, 需要把数字转换成十六进制再查询 UTF-8 码表

1.2, 每次输入多个字节

要想一次输入多个字节, 就创建一个字节数组, 调用 inputStream.read(字节数组), 最多读取数组长度大小个字节, 返回数组长度, 读完了返回 -1

        // 输入流  从硬盘读到内存
        try(InputStream inputStream = new FileInputStream("D:/hello.txt")) {
            byte[] array = new byte[1024];
            while(true) {
                int ret = inputStream.read(array);
                if(ret == -1) {
                    // 说明读完了
                    break;
                }
                for(int i = 0; i < ret; i++) {
                    System.out.println(array[i]);
                }
            }
        }

这种方式从文件读取数据的次数更少, 性能要更好


2, 字节流输出 OutputStream

2.1, 每次输出一个字节

和 InputStream 类似, 针对文件的输出对应的类是 FileOutputStream

调用 outputStream.write(整形), 可以每次输出一个字节

        try(OutputStream outputStream = new FileOutputStream("D:/hello.txt")) {
            outputStream.write(97);
            outputStream.write(98);
            outputStream.write(99);
        }

这样就可以在文件中依次写入"abc", 如图 :
在这里插入图片描述

接着再写入一些数据到文件

        try(OutputStream outputStream = new FileOutputStream("D:/hello.txt")) {
            outputStream.write(100);
            outputStream.write(101);
            outputStream.write(102);
        }

查看文件中, 如图 :
在这里插入图片描述

发现原本的"abc" 三个字符没有了, 这是因为第二次写入的数据把之前的数据覆盖了, 只需要在实例化 outputStream 的构造方法中多给一个参数 “true”, 表示在之前的数据末尾 append 要写入的数据

// 输出流 从内存写到硬盘
        try(OutputStream outputStream = new FileOutputStream("D:/hello.txt",true)) {
            outputStream.write(100);
            outputStream.write(101);
            outputStream.write(102);
        }

查看文件中的数据如图 :
在这里插入图片描述


2.2, 每次输出多个字节

和 InputStream 类似, 要想每次输出多个字节, 需要创建一个字符数组, 调用 outputStream.write(字符数组), 就可以把字符数组中的所有数据写入到文件

        // 输出流 从内存写到硬盘
        try(OutputStream outputStream = new FileOutputStream("D:/hello.txt", true)) {
            byte[] array = {103, 104, 105};
            outputStream.write(array);
        }

查看文件中的数据, 如图 :
在这里插入图片描述



总结

以上就是本篇的全部内容, 都相对比较简单, 只是方法比较繁多, 需要小伙伴们多加练习

如果本篇对你有帮助,请点赞收藏支持一下,小手一抖就是对作者莫大的鼓励啦😋😋😋~


上山总比下山辛苦
下篇文章见

在这里插入图片描述

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

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

相关文章

chatgpt赋能Python-python3__2怎么算

Python3中<<2的计算方法 Python3是一种高级编程语言&#xff0c;它具有强大的数据分析和计算能力。在Python3中&#xff0c;<<2是一种用于移位计算的运算符。在本篇文章中&#xff0c;我们将介绍Python3中<<2的计算方法。 什么是移位运算符 移位运算符是一…

C++基础语法——内存管理

1. C/C中的内存管理 我们先看如下一段代码 #include <iostream>using namespace std;int globalVar 1; static int staticGlobalVar 1;void Test() {static int staticVar 1;int localVar 1;int num1[10] { 1, 2, 3, 4 };char char2[] "abcd";const ch…

rk3399 buildroot ubuntu20版本编译遇到问题

一、编译uboot遇到问题 /usr/include/libfdt.h:258:1: error: redefinition of fdt_set_version 258 | fdt_set_hdr_(version); | ^~~~~~~~~~~~ In file included from tools/fdt_host.h:11, from tools/imagetool.h:22, from tools…

BurpSuite—-Target模块(目标模块)

前言 本文主要介绍BurpSuite—-Target模块(目标模块)的相关内容 关于BurpSuite的安装可以看一下之前这篇文章&#xff1a; http://t.csdn.cn/cavWt Target功能 目标工具包含了SiteMap&#xff0c;用你的目标应用程序的详细信息。它可以让你定义哪些对象在范围上为你目前的工…

基于QGIS的长株潭城市群边界范围融合实战

背景 在面向区域的研究过程中&#xff0c;比如一些研究区域&#xff0c;如果是具体的行政区划&#xff0c;比如具体的某省或者某市或者县&#xff0c;可以直接从国家官方的地理数据中直接下载就可以。但如果并没有直接的空间数据那怎么办呢&#xff1f;比如之前遇到的一个场景&…

chatgpt赋能Python-python3_len__

Python3 len()函数&#xff1a;使用方法和常见应用 在Python中&#xff0c;len()函数是一个内置函数&#xff0c;用于返回对象的长度或元素的个数。它适用于字符串、列表、元组、字典、集合等Python数据类型。在本篇文章中&#xff0c;我们将深入探讨Python3 len()函数的使用方…

C++ [STL之string模拟实现]

本文已收录至《C语言和高级数据结构》专栏&#xff01; 作者&#xff1a;ARMCSKGT STL之string模拟实现 前言正文存储结构默认成员函数构造函数析构函数拷贝构造函数赋值重载 容量操作类获取字符串长度size获取当前容量capacity查询是否为空串emptyreserve扩容调整字符串大小si…

基于Freertos的ESP-IDF开发——6.使用DHT1温湿度传感器

基于Freertos的ESP-IDF开发——6.使用DHT1温湿度传感器 0. 前言1. DHT11驱动原理2. 完整代码3. 演示效果4. 其他FreeRtos文章 0. 前言 开发环境&#xff1a;ESP-IDF 4.3 操作系统&#xff1a;Windows10 专业版 开发板&#xff1a;自制的ESP32-WROOM-32E 准备一个DHT11温湿度传…

【Element-ui】el-table大数据量渲染卡顿问题

1、场景描述 在项目开发中&#xff0c;遇到在表格中一次性加载完的需求&#xff0c;且加载数量不少&#xff0c;有几百几千条&#xff0c;并且每条都可能有自己的下拉框&#xff0c;输入框来做编辑功能&#xff0c;此时普通的el-table肯定会导致浏览器卡死&#xff0c;那么怎么…

Windows10 双网卡配置,轻松实现内外互通

1 背景 我平常需要连接外网查阅资料&#xff0c;聊天等&#xff0c;做实验时需要将写到的代码打包部署到内网服务器中&#xff0c;所以需要频繁地切换内外网&#xff0c;修改静态网络配置。很是苦恼。 2 方法 最近&#xff0c;我找到了几种解决办法。 方法一、…

uniapp DIY可视化工具 控件拖拽工具怎么开发/拖拽库/模板引擎

uniapp DIY可视化工具 控件拖拽工具怎么开发 答&#xff1a;需要 (**拖拽库**) &#xff08;**模板引擎**&#xff09;代码自动生成 python有哪些模板引擎 Jinja2是一个小型但快速且易于使用的以纯python编写的独立模板引擎&#xff08;最主要的模板&#xff09;Chameleon是T…

深度学习之卷积神经网络(CNN)

大家好&#xff0c;我是带我去滑雪&#xff01; 卷积神经网络&#xff08;Convolutional Neural Network&#xff0c;CNN&#xff09;是一种基于深度学习的前馈神经网络&#xff0c;主要用于图像和视频识别、分类、分割和标注等计算机视觉任务。它主要由卷积层、池化层、全连接…

【开源、应用】QT—TCP网络上位机的设计

本文设计一个终端控制的上位机软件&#xff08;如“设计目标”下图所示&#xff09;&#xff0c;可以和STM32、Adruino等通信实现无线局域网控制系统。 本文的通信内容和图表内容可以参考作者之前的文章 STM32ESP8266连接电脑Qt网络上位机——QT篇https://blog.csdn.net/qq_53…

【STM32G431RBTx】备战蓝桥杯嵌入式→决赛试题→第六届

文章目录 前言一、题目二、模块初始化三、代码实现interrupt.h:interrupt.c:main.h:main.c: 四、完成效果五、总结 前言 无 一、题目 二、模块初始化 1.LCD这里不用配置&#xff0c;直接使用提供的资源包就行 2.ADC:开启ADCsingle-ended 3.LED:开启PC8-15,PD2输出模式就行了…

【JVM001】宋红康JVM字节码举例

宋红康JVM字节码举例 1 Integer package jvmT; public class IntegerTest {public static void main(String[] args) {Integer i 5;int y 5;System.out.println(iy); //trueInteger i6 5;Integer y6 5;System.out.println(i6y6);//trueInteger i5 128;Integer y5 128;System.…

SpringBoot中使用lombok

1.添加依赖 在项目的根目录中找到pom.xml&#xff0c;在dependencies下复制这段代码 <!-- https://mvnrepository.com/artifact/org.projectlombok/lombok --><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifac…

解决Python爬虫中selenium模块中的find_element_by_id方法无法使用

如有错误&#xff0c;敬请谅解&#xff01; 此文章仅为本人学习笔记&#xff0c;仅供参考&#xff0c;如有冒犯&#xff0c;请联系作者删除&#xff01;&#xff01; 我们在学习selenium模块的时候&#xff0c;经常会用到 browser.find_element_by_id命令&#xff0c;但随着se…

代码随想录算法训练营第四十六天 | bool的背包题,细节多

139.单词拆分 文档讲解&#xff1a;代码随想录 (programmercarl.com) 视频讲解&#xff1a;动态规划之完全背包&#xff0c;你的背包如何装满&#xff1f;| LeetCode&#xff1a;139.单词拆分_哔哩哔哩_bilibili 状态&#xff1a;不会做&#xff0c;不知道怎么把bool类型与背包…

推荐系统系列之推荐系统概览(下)

在推荐系统概览的第一讲中&#xff0c;我们介绍了推荐系统的常见概念&#xff0c;常用的评价指标以及首页推荐场景的通用召回策略。本文我们将继续介绍推荐系统概览的其余内容&#xff0c;包括详情页推荐场景中的通用召回策略&#xff0c;排序阶段常用的排序模型&#xff0c;推…

软件测试实验:loadrunner的高级使用

目录 前言实验目的实验内容实验要求实验过程loadrunner中插入事务与集合点loadrunner中插入检查点loadrunner中参数化-table分析报告功能loadrunner手动设置场景loadrunner监视图标 总结 前言 本实验主要介绍了loadrunner这一强大的性能测试工具的高级使用方法&#xff0c;包括…