【JavaEE初阶】第四节.文件操作 和 IO (下篇)

news2024/11/16 7:23:44

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录


前言

这篇博客是关于 文件操作和IO 的下半篇的内容,主要介绍的是 文件内容的各种操作 ;

三、文件内容的操作 

关于文件读写的操作,主要分为这几大块:打开文件、关闭文件、读文件、写文件 ;

其中,读写文件 是关键操作 ;

但是,在读写文件之前,必须要打开文件;在使用完毕之后,必须要关闭文件 ;

在 Java中,关于文件读写,提供了几组相关的类(是父类,还有许多其他子类继承):

  1. 第一组:InputStream类、OutputStream类 ——> 字节流(以字节为单位的流,用来操作二进制文件的)
  2. 第二组:Reader类、Writer类 ——> 字符流(以字符为单位的流,用来操作文本文件的)

关于 "流",是计算机中一种常见的概念 ;

比如说,如果想接住 100ml的水 ;

可以一次接 100ml,一次就搞定;可以一次接 50ml,两次就搞定;可以一次接 10ml,十次就搞定 ......

类似于水流,可以随心所欲的控制 读写的数据量 

如:想 读/写 100字节的数据 ~

可以一次 读/写100字节,一次就搞定;可以一次 读/写50字节,两次就搞定;可以一次 读/写10字节,十次就搞定 ......

于是,我们就把这种 读/写 方式,称为 面向流的读/写方式 ;


3.1 读文件

3.1.1 使用字节流读文件

我们可以在 Idea 上输入 InputStream类,点击 Ctrl + 左键,便可以发现,InputStream 是一个抽象类,不可以直接 new,需要使用 new InputStream 子类的方式来进行实例化: 

方法:

关于 InputStream类 的常用方法有下面几个:

需要注意的是,要在打开之后 一定记得要关闭文件!!!

—— 需要释放资源(内存、文件描述符表)

—— 如果打开文件之后,忘记关闭,造成的结果非常大的(文件资源泄露,就像是定时炸弹一样,并不是马上就泄露完,这就非常的麻烦了)

一个进程,会使用PCB来描述(此时 只考虑单线程)

PCB 里面有很多属性,文件描述符表 就是其中的一个属性,它可以看作是一个数组(顺序表),其中的每个元素 都对应着当前打开的文件,这个数组的下标 就称为 "文件描述符" ~

每次打开文件,都会在文件描述符表中 占据一个位置,每次关闭文件,都会释放一个位置;由于文件描述符表的长度是存在上限的,所以如果一个线进程一直在打开文件,没有释放文件,此时就会导致 后续进程在打开的时候失败!!!

代码示例:

package file;
 
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
 
public class Demo6 {
    //使用一下 InputStream类
    public static void main(String[] args) throws IOException {
        // 1.打开文件
        //打开文件成功,就得到了 InputStream对象,
        //后续针对文件的操作,都是通过 InputStream 来展开的
        // (就相当于是 空调遥控器 可以操控空调,内存中的 InputStream对象 可以操控硬盘里面的 test2.txt文件)
        //像 inputStream 这一类的 “遥控器”,在计算机中 我们通常称为:句柄(Handler)
        InputStream inputStream = new FileInputStream("./test2.txt");
 
        // 2.读取文件
        while (true) {
            int b = inputStream.read();
            if(b == -1) {
                //此时,文件读完了
                break;
            }
            System.out.println(b);
        }
 
        // 3.关闭文件
        //关闭文件,以释放 内存资源 和 文件描述符表
        inputStream.close();
    }
}

同时,我在 test2.txt 文件下输入了:hello 

运行结果:


-- 当然,我们也可以采用其他的 read方法 来读取数据
-- 这里可以把 2.读取文件 的代码改成:
        byte[] b = new byte[1024];
        int len = inputStream.read(b);
        System.out.println(len);
        for (int i = 0; i < len; i++) {
            System.out.println(b[i]);
        }

 此时,运行的结果是:

 3.1.2 使用字符流读文件 

需要注意的是,在上面的 test2.txt 文件中 存储的是英文状态的 "hello",但是但我们把它改成中文状态的 "你好" 时,那结果可就不一样了 ;

运行结果:

 说明:

当前格式 是 utf-8 的格式编码,它的汉字一般是 三个字节一个汉字 

如果想要直观的获取 中文,那就需要去手动的转换(如下所示):

-- 这里可以把 2.读取文件 的代码改成:
        byte[] b = new byte[1024];
        int len = inputStream.read(b);
        //把 0到len 这一段数据构成一个字符串,并且指定构造字符集的格式编码 —— utf-8
        String s = new String(b,0,len,"utf-8");
        System.out.println(s);

运行结果:


通过字节流,读取文本数据的时候,虽然可以读取到,但是要想真正还原成原始的版本,还是比较麻烦的,需要手动处理;

因此就可以使用 字符流 来解决上述问题(字符流 就相当于已经在底层 已经完成了里面的转换了);


代码示例:

package file;
 
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
 
public class Demo7 {
    //使用字符流读文件
    public static void main(String[] args) throws IOException {
        Reader reader = new FileReader("test2.txt");
        char[] buffer = new char[1024];
        int len = reader.read(buffer);
        for (int i = 0; i < len; i++) {
            System.out.print(buffer[i]);
        }
        //关闭资源
        reader.close();
    }
}

运行结果:

3.1.3 使用Scanner读取文件(推荐)

 字符流来处理文本是比较方便的,但是 这里还有一种更为简单的方法,可以使用 Scanner 来读取文本文件 ;

Scanner scanner = new Scanner(System.in);
//以前我们使用的是这个样子的,可以从键盘上来输入数据
//其中,System.in 中的 in 就是 inputStream
//如果直接把 System.in 换成 inputStream
//需要 InputStream inputStream = new FileInputStream("文本");
//就可以去读自己写的文件

代码示例:

package file;
 
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.Scanner;
 
public class Demo8 {
    //使用 Scanner 来读取文本文件
    public static void main(String[] args) throws IOException {
        InputStream inputStream = new FileInputStream("test2.txt");
        Scanner scanner = new Scanner(inputStream);
        String s = scanner.next();
        System.out.println(s);
        
        inputStream.close();
    }
}

运行结果:

需要注意的是,其实在上述代码中,涉及到了 read操作,这就会引出 IOException异常,此时代码就会无法进行,后面的 关闭文件(close ) 的操作就不会被运行 ;

所以可以使用 try ... catch ... finally ... 的操作来避免的 ;

这里就不做过多演示了 ;

但是,最后就会发现,这个看起来就很啰嗦 ;

所以,就可以改成这个样子了 :

这样的操作叫做 try with resource(有资源的 try);

同时,这类写法 会在 try 实现结束之后,自动调用 inputStream 的 close方法(当然,并不是所有的类都可以这样放在try括号里面,要求这个类实现 Closeable接口,才可以这么做);

这种写法是比较推荐的写法;

 3.2 写文件

字节流:OutputStream / FileOutputStream

字符流:Writer / FileWriter

以及,和 Scanner 相对的 PrintWriter 操作

OutoutStream类 的方法和上面的 InputStream类 的方法差不多,这里就不做过多介绍了,感兴趣的铁铁们可以自己去看看官方文档 ;

3.2.1 使用字节流写文件

package file;
 
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
 
public class Demo10 {
    public static void main(String[] args) {
        try(OutputStream outputStream = new FileOutputStream("test2.txt")) {
            //写文件
            outputStream.write('h');
            outputStream.write('e');
            outputStream.write('l');
            outputStream.write('l');
            outputStream.write('o');
        }catch (IOException e) {
            e.printStackTrace();
        }
    }
}

当我们运行这段代码时,再去查看 text2.txt 文档时,就会发现:

 如果想写一个字符串,那么就可以这样做:

package file;
 
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
 
public class Demo10 {
    public static void main(String[] args) {
        try(OutputStream outputStream = new FileOutputStream("test2.txt")) {
            //写文件
            String s = "hello java";
            outputStream.write(s.getBytes());
        }catch (IOException e) {
            e.printStackTrace();
        }
    }
}

此时,运行程序后,再去看看 test2.txt 文件,就会发现:

注意的是,每一次 写文件 的操作都会清空原有的文件,然后再去重新写 ; 

3.2.2 使用字符流写文件 

package file;
 
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
 
public class Demo11 {
    public static void main(String[] args) {
        try(Writer writer = new FileWriter("test2.txt")) {
            writer.write("hello world");
        }catch (IOException e)  {
            e.printStackTrace();
        }
    }
}

此时,运行程序之后,再次看看 test2.txt 文件,就会发现:

3.2.3 使用PrintWriter写文件

package file;
 
import java.io.*;
 
public class Demo12 {
    public static void main(String[] args) {
        try (OutputStream outputStream = new FileOutputStream("test2.txt")) {
            //此处的 PrintWriter 的用法 和 System.out 有相似之处
            PrintWriter printWriter = new PrintWriter(outputStream);
            printWriter.println("正在看博客的人好帅啊");
            printWriter.flush();
        }catch (IOException e) {
            e.printStackTrace();
        }
    }
}

此时,程序运行结束之后,再来看看 test2.txt 文件:

 

 四、代码案例


总结

现在,关于文件操作的有关 内容就结束了,一定要熟练掌握有关文件操作的各个方法和理解其含义;

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

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

相关文章

信捷 XDH Ethercat A_VELMOVE

本文描述信捷 EthercatA_VELMOVE指令&#xff0c;以设定的速度持续运行 上图中&#xff0c;在M100的上升沿&#xff0c;执行A_VELMOVE指令。A_VELMOVE HD100 D100 M101 K0HD100输入参数起始地址 &#xff0c;HD118输入参数末尾地址HD100~HD103,双精度浮点数&#xff08;64位&am…

【剧前爆米花--爪哇岛寻宝】Java实现无头单向非循环链表和无头双向链表与相关题目

作者&#xff1a;困了电视剧 专栏&#xff1a;《数据结构--Java》 文章分布&#xff1a;这是关于数据结构链表的文章&#xff0c;包含了自己的无头单向非循环链表和无头双向链表实现简单实现&#xff0c;和相关题目&#xff0c;想对你有所帮助。 目录 无头单向非循环链表实现 …

Web Components学习(1)

一、什么是web components 开发项目的时候为什么不手写原生 JS&#xff0c;而是要用现如今非常流行的前端框架&#xff0c;原因有很多&#xff0c;例如&#xff1a; 良好的生态数据驱动试图模块化组件化等 Web Components 就是为了解决“组件化”而诞生的&#xff0c;它是浏…

4.Elasticsearch深入了解

4.Elasticsearch深入了解[toc]1.Elasticsearch架构原理Elasticsearch的节点类型在Elasticsearch主要分成两类节点&#xff0c;一类是Master&#xff0c;一类是DataNode。Master节点在Elasticsearch启动时&#xff0c;会选举出来一个Master节点。当某个节点启动后&#xff0c;然…

A Star算法最通俗易懂的一个版本

01-概述虽然掌握了 A* 算法的人认为它容易&#xff0c;但是对于初学者来说&#xff0c; A* 算法还是很复杂的。02-搜索区域(The Search Area)我们假设某人要从 A 点移动到 B 点&#xff0c;但是这两点之间被一堵墙隔开。如图 1 &#xff0c;绿色是 A &#xff0c;红色是 B &…

猿创征文 | re:Invent 朝圣之路:“云“行业风向标

&#x1f497;wei_shuo的个人主页 &#x1f4ab;wei_shuo的学习社区 &#x1f310;Hello World &#xff01; AWS 亚马逊云科技re:Invent全球大会 2022年亚马逊云科技re:Invent全球大会震撼来袭&#xff0c;即将于北京时间11月30日-12月2日在美国内华达州&#xff0c;拉斯维加斯…

【MySQL】将 CSV文件快速导入 MySQL 中

【MySQL】将 CSV文件快速导入 MySQL 中方法一&#xff1a;使用navicat等软件的导入向导如果出现中文乱码方法二&#xff1a;命令行导入&#xff08;LOAD DATA INFILE SQL&#xff09;一般来说&#xff0c;将csv文件导入mysql数据库有两种办法&#xff1a; 使用 navicat、workbe…

易优cms links 友情链接调用标签

links 友情链接调用 【基础用法】 标签&#xff1a;links 描述&#xff1a;用于获取友情链接列表。 用法&#xff1a; {eyou:links typetext loop30 titlelen15} <a href{$field.url} {$field.target} {$field.nofollow}>{$field.title}</a> {/eyou:links} …

模型杂谈:快速上手元宇宙大厂 Meta “开源泄露”的大模型(LLaMA)

本篇文章聊聊如何低成本快速上手使用 Meta&#xff08;Facebook&#xff09;的开源模型 LLaMA。 写在前面 在积累点赞&#xff0c;兑现朋友提供的显卡算力之前&#xff0c;我们先来玩玩“小号的”大模型吧。我相信 2023 年了&#xff0c;应该不需要再赘述如何使用 Docker 干净…

Go的 context 包的使用

文章目录背景简介主要方法获得顶级上下文当前协程上下文的操作创建下级协程的Context场景示例背景 在父子协程协作过程中, 父协程需要给子协程传递信息, 子协程依据父协程传递的信息来决定自己的操作. 这种需求下可以使用 context 包 简介 Context通常被称为上下文&#xff…

AUTOSAR知识点Com(六):CANIf规范时序图

目录 1、概述 2、规范时序 2.1、Transmit request (single CAN Driver) 2.2、Transmit request (multiple CAN Drivers) 2.3、Transmit confirmation (interrupt mode) ​2.4、Transmit confirmation (polling mode) 2.5、Transmit confirmation (with buffering) 2.6、T…

国际物流是怎么给货物打包的

国际物流常见的包装方法有好几种&#xff0c;而且国际物流公司针对物品的包装都是格外重视&#xff0c;国际物流公司会依据物品的不同种类搭配不同的包装&#xff0c;便于物品完好无损的到的目的地。包装无论大小形态&#xff0c;它的核心目的是为了保护性、分辨性与便利性&…

使用pybind11将c++扩展为python

pybind11—python C/C扩展编译 - 简书 (jianshu.com)pybind11在Windows下的使用 - 酱_油 - 博客园 (cnblogs.com)编写 Python 的 C 扩展 - Visual Studio (Windows) | Microsoft Learn首先安装pybind11并在VS中配置安装pybind11&#xff1a;mirrors / pybind / pybind11 GitCo…

数据结构与算法---JS与栈

前言js里&#xff0c;是没有栈这种原生的数据结构。但是我们可以通过自定义创建栈类&#xff0c;来实现对添加/删除元素时更多的控制。创建栈类// 初始化一个基于数组的栈类 class Stack {constructor() {this.items [];} }为什么我们要选择数组作为栈类的存储数据类型&#x…

23.3.9打卡 AtCoder Beginner Contest 259

A题 题解 对于x特判一下就好 代码 void solve() {ll x,d;cin>>n>>m>>x>>t>>d;if(n>m){nmin(n,x);if(n<m){cout<<t;return;}cout<<(m-n)*dt;}else{mmin(m,x);cout<<(m-n)*dt;}return; }B 三角函数全还给高中老师了 题…

ARM 学习(一)

ARM 处理器的运行模式ARM处理器共有7种运行模式&#xff0c;如下表所示&#xff1a;处理器模式描述用户模式&#xff08;User&#xff09;正常程序运行模式中断模式&#xff08;IRQ&#xff09;用于通常的中断处理快速中断模式&#xff08;FIQ&#xff09;用于高速传输和通道处…

qt控件增加渐变色效果

ui->returnBtn->setStyleSheet("color: rgb(0, 0, 0);""background:qlineargradient(spread:pad, x1:0, y1:1, x2:0, y2:0, ""stop:0 #5f5f5f, stop:0.5 #ffffff, stop:0.98 #5f5f5f);""border:none;");效果如下图&#xff1a; …

java-3月xly笔记

时间安排&#xff1a; 朱祥祥 会议号&#xff1a;417 523 3263 服务器&#xff1a;doc.canglaoshi.org jdk下载&#xff1a;https://repo.huaweicloud.com/java/jdk/ jdk配置环境变量 检测命令&#xff1a; &#xff08;1&#xff09;winr&#xff0c;输入cmd&#xff0c…

ActiveMQ反序列化漏洞原理+复现

ActiveMQ反序列化漏洞 ActiveMQ ActiveMQ是开源消息总线&#xff0c;消息中间件 工作原理 通过使用消息队列&#xff0c;实现服务的异步处理&#xff0c;主要目的是减少请求响应时间和解耦合。 消息队列&#xff0c;服务器A将客户发起的请求放入服务器B的消息队列中&#…

裸辞两个月还能不能找到工作?亲身经历告诉你结果·····

这是我在某论坛看到的一名网友的吐槽&#xff1a; 软件测试四年&#xff0c;主要是手动测试&#xff08;部分自动化测试和性能测试&#xff0c;但是用的是公司内部自动化工具&#xff0c;而且我自动化方面是弱项。&#xff09;现在裸辞两个月了&#xff0c;面试机会少而且面试…