【JavaEE】_文件与IO

目录

 1.文件概述

1.1 文件的概念

1.2 文件的存储

1.3 文件的分类

1.4 目录结构

1.5 文件操作

1.5.1 文件系统操作

1.5.2 文件内容操作

2. Java文件系统操作

2.1 File类所处的包

2.2 构造方法

2.3 方法

2.3.1 与文件路径、文件名有关的方法

2.3.2 文件是否存在与普通文件、目录的判定的方法

2.3.3 文件的创建与删除的方法

2.3.4 目录的创建方法

2.3.5 罗列目录文件的方法

 2.3.6 文件的重命名操作

 3.Java文件内容操作

3.1 FileInputStream  字节流的读操作

3.2  FileOutputStream  字节流的写操作

3.3 Reader  字符流的读操作

3.4 Writer  字符流的写操作

4. 文件操作的应用


 1.文件概述

1.1 文件的概念

狭义文件概念:

平时说的文件一般都是存储在硬盘上的普通文件:形如.txt  .jpg  .mp4  rar等都可认为是普通文件,他们都是在硬盘上存储的;

广义文件概念:

在计算机中文件也可以是一个广义的概念,就不只是包含普通文件,还可以包含目录(目录文件),也就是俗称的文件夹,操作系统中还会使用文件来描述一些其他的硬件设备或软件资源:比如操作系统中将网卡、显示器、键盘等这样的硬件设备也抽象成了一个文件;

当前讨论的文件仍然是针对普通文件;

1.2 文件的存储

普通文件是保存在硬盘上的;

机械硬盘包括磁头与存储数据的介质:盘片,机械硬盘一旦上电,盘片就会高速运转,磁头在盘片上找到对应的数据。

但是由于机械硬盘的机械构造,盘片转速越高,读写速度就越快,但是因为工艺的限制,盘片转速也不可能无限高,机械硬盘的读写速度已经多年停滞不前,而是向大容量方向发展;

故而从硬盘上读取数据就要比从内存读取数据要慢很多,大约是3~4个数量级;

因为flash芯片的使用,固态硬盘的速度就要比机械硬盘高很多;

当前学习中就以机械硬盘为主,即文件数据读取的特点为:存储空间更大,读取速度更慢;

1.3 文件的分类

一般情况下文件主要分为两类:文本文件与二进制文件,两种文件在编程时会存在差异;

文本文件中存储的是字符,二进制文件中存储的是字节;

判断一个文件是文本文件还是二进制文件最简单的方法就是使用记事本打开该文件,如果打开后是乱码则为二进制文件,否则就是文本文件:

日常中使用的.txt  .c  .java都属于文本文件

而.doc  .ppt  .exe  .zip  .class 等都是二进制文件

(word保存的不是一个单纯的文本,而是一个带有各种格式化信息的“富文本”)

1.4 目录结构

计算机中保存管理文件是通过操作系统中的“文件系统“模块”进行管理的,在文件系统中一般是通过“树形”结构来组织磁盘上的目录和文件的,如:

如果是一个普通文件,就是树的叶子结点;

如果是一个目录文件,目录中就可以包含子树,这个目录就是非叶子结点;

在操作系统中,就通过“路径”概念来描述一个具体文件或目录的位置:

(1)绝对路径:以盘符开头,如:E:\JavaEE_FilesAndIO\src\Main.java 就是一个绝对路径;

(2)相对路径:以.或..开头,其中.表示当前路径,..表示当前路径的父目录(上级路径)。

相对路径实现必须有一个基准目录,相对路径就是从基准目录出发,按照一个路径找到对应文件,

例如:以E:\JavaEE_FilesAndIO为基准目录,找到Main.java文件,就可以表示为.\src\Main.java;

E:\Java_String\src目录中也存在一个Main.java文件,如果此时仍以E:\JavaEE_FilesAndIO为基准目录,找到Main.java文件,就需要表示为:..\src\Main.java;

即:.表示基准路径,..表示基准路径的上一级目录

即使定位到同一个文件,如果基准目录不同,此时相对路径也不同;

1.5 文件操作

java中的文件操作主要包括两类:文件系统相关操作与文件内容相关操作;

1.5.1 文件系统操作

文件系统操作指的是通过“文件资源管理器”能够完成的一些功能,如:

① 列出目录下的文件 ② 创建文件 ③ 创建目录 ④ 删除目录 ⑤ 重命名文件等等;

Java提供了一个File类来完成上述操作,这个File类描述了一个文件或目录,基于这个对象就可以实现上面的功能;

1.5.2 文件内容操作

类似于C语言的文件操作,即:

① 打开文件 ② 读文件  ③ 写文件  ④ 关闭文件

Java提供了一组类来实现对文件内容的操作:

(1)按照文件内容,分为两个系列:

字节流对象(针对二进制文件,以字节为单位进行读写)与字符流对象(针对文本文件,以字符为单位进行读写);

(2)

以下内容将对于java文件的系统操作与内容操作分别进行阐述:

2. Java文件系统操作

2.1 File类所处的包

import java.io.File;

2.2 构造方法

//绝对路径
File f1= new File("E:/JavaEE_FilesAndIO:/file2.txt");
//相对路径:基准路径取决于运行java程序的方式
File f2= new File("./file3.txt");

运行java程序的方式:

(1)命令行方式(java Demo1),此时执行命令所在的目录就是基准路径,实际不考虑该情况;

(2)IDEA方式,此时基准路径就是当前java项目所在路径,如此时的项目所在位置为:

(3)如果将一个java程序达成war包置于tomcat上运行,此时基准路径就是tomcat的bin目录;

如果路径指定错了,很容易出现找不到文件的情况;

2.3 方法

2.3.1 与文件路径、文件名有关的方法

//绝对路径
File f1= new File("E:/file2.txt");
System.out.println(f1.getParent());   //获取父目录
System.out.println(f1.getName());     //获取文件名
System.out.println(f1.getPath());     //获取文件路径(构造File时指定的路径)
System.out.println(f1.getAbsolutePath());//获取绝对路径
System.out.println(f1.getCanonicalPath());// 获取绝对路径System.out.println("-----------------------------");//相对路径:基准路径取决于运行java程序的方式File f2= new File("./file3.txt");
System.out.println(f2.getParent());   //获取父目录
System.out.println(f2.getName());     //获取文件名
System.out.println(f2.getPath());     //获取文件路径(构造File时指定的路径)
System.out.println(f2.getAbsolutePath());//获取绝对路径
System.out.println(f2.getCanonicalPath());// 获取绝对路径

输出结果为:

注:"/" 读作斜杠, "\"读作反斜杠;

File类中pathSeparator属性就是相邻路径之间的分隔符,一般情况下,大部分操作系统上路径的分隔符都是斜杠,而Windows默认使用的是反斜杠,但斜杠与反斜杠都可被系统识别;

2.3.2 文件是否存在与普通文件、目录的判定的方法

基于当前项目路径下包含的目录与文件如下:

 试运行以下代码:

        File f= new File("./file1.txt");System.out.println(f.exists());   //文件是否存在System.out.println(f.isDirectory()); //文件是否为目录System.out.println(f.isFile());   // 文件是否是一个普通文件

输出结果为:

2.3.3 文件的创建与删除的方法

        File f = new File("./file2.txt");System.out.println(f.exists());System.out.println("The file is absent,create a file now.");f.createNewFile();System.out.println("Finish creating a file.");System.out.println(f.exists());f.delete();System.out.println("Finish deleting the file");System.out.println(f.exists());

输出结果为:

注:java还提供了一个deleteOnExit()的方法进行程序退出后再删除,使用较少;

2.3.4 目录的创建方法

(1)单个目录:

        File f = new File("./aaa");f.mkdir();    //创建目录System.out.println(f.isDirectory());   //判断是否为目录

 输出结果为:

(2)多级目录:

        File f = new File("./aaa/bbb/ccc/ddd");f.mkdirs();    //创建多级目录System.out.println(f.isDirectory());   //判断是否为目录

 输出结果为:

可从左侧Project栏查看对应目录与文件: 

2.3.5 罗列目录文件的方法

        File f = new File("./");System.out.println(Arrays.toString(f.list()));   //返回字符串数组System.out.println(Arrays.toString(f.listFiles()));   //返回File数组

 输出结果为:

 2.3.6 文件的重命名操作

        File f1 = new File("./aaa");File f2 = new File("./zzz");f1.renameTo(f2);  //将aaa改名为zzz

可从左侧Project栏查看对应目录与文件: 

 3.Java文件内容操作

3.1 FileInputStream  字节流的读操作

 

 read提供了三个版本的重载:

① 无参:一次读一个字节;

② 一参:一次读若干个字节,将读到的结果存入参数数组中,返回值是读到的字节数;

③ 三参:一次读若干个字节,将读到的结果存入参数数组中,返回值是读到的字节数,可指定元素放置数组的位置下标off以及最多能放多少个元素len

 (字符流也有类似的设定,为了方便char类型的读取,选择了int而非short)

基于E:\JavaEE_FilesAndIO路径下file1.txt文件内存有abcdef,试运行:

代码示例1:一次读取一个字节:

        //方法中需要指定打开文件的路径(绝对路径、相对路径或File对象)try {//创建对象,同时也打开文件InputStream inputStream = new FileInputStream("./file1.txt");//尝试按照字节进行读取while(true) {int b = inputStream.read();if (b == -1) {//读到了文件末尾break;}System.out.println(b);}//关闭文件并释放资源inputStream.close();}catch(FileNotFoundException e) {//FileNotFoundException是IOException的一个子类,故而可以进行合并e.printStackTrace();}catch(IOException e){//读操作可能发生的异常:IO操作失败的可能性是非常大的e.printStackTrace();}

 输出结果为:

 这些数字就是每个字符的ASCII码值(英文字符本身就是一个字节)

代码改进1:

但是这种编写方式会导致:如果文件不存在抛出异常时会跳过关闭文件,导致释放资源失败,故而需要将close方法置于finally中,修改代码如下:

        //方法中需要指定打开文件的路径(绝对路径、相对路径或File对象)InputStream inputStream = null;try {//创建对象,同时也打开文件inputStream = new FileInputStream("./file1.txt");//尝试按照字节进行读取while(true) {int b = inputStream.read();if (b == -1) {//读到了文件末尾break;}System.out.println(b);}}catch(FileNotFoundException e) {//FileNotFoundException是IOException的一个子类,故而可以进行合并e.printStackTrace();}catch(IOException e){//读操作可能发生的异常:IO操作失败的可能性是非常大的e.printStackTrace();}finally{try {//关闭文件并释放资源inputStream.close();}catch(IOException e){e.printStackTrace();}}

代码改进2:

但是这样的编写方式是非常麻烦的,java中提供了一个语法:try with resources:

try(InputStream inputStream = new FileInputStream("./file1.txt")){while(true){int b = inputStream.read();if(b == -1){break;}System.out.println(b);}}catch(IOException e){e.printStackTrace();}

 以上代码中没有显式手动调用close,但是try会帮我们自动调用:

当代码执行完这里的try语句块之后,就会自动调用close;

注:需要实现Closeable interface才能置于try()中,所有的流对象都实现了Closeable

代码示例2:一次读取若干个字节:

        try(InputStream inputStream = new FileInputStream("./file1.txt")){//一次读取若干个字节while(true){//将读出的结果置于buffer数组中,相当于用参数表示方法返回值,这种方法称为输出型参数byte[] buffer = new byte[1024];int len = inputStream.read(buffer);if(len == -1){break;}for(int i=0;i<len;i++){System.out.println(buffer[i]);}}}catch(IOException e){e.printStackTrace();}

实际使用中这样的读取方式才是常见且高效的;

3.2  FileOutputStream  字节流的写操作

现将E:\JavaEE_FilesAndIO路径下file1.txt文件原存内容全部清空,试运行:

代码示例1:一次写入一个字节:

        try(OutputStream outputStream = new FileOutputStream("./file1.txt")){outputStream.write('a');outputStream.write(98);outputStream.write(99);}catch(IOException e){e.printStackTrace();}

打开对应文件:

代码示例2:一次写入多个字节:

        try(OutputStream outputStream = new FileOutputStream("./file1.txt")){byte[] buffer = new byte[]{97,98,99};outputStream.write(buffer);}catch(IOException e){e.printStackTrace();}

打开对应文件:

注:每次按照“写”方式打开文件,都会清空文件原有内容,再从起始位置往后写

故而也存在追加写的流对象,打开之后不清空,继上次文件内容后继续往后写;

3.3 Reader  字符流的读操作

基于对应文件中存储有“abc”的file1.txt文件,试运行如下代码:

        try(Reader reader = new FileReader("./file1.txt")){//按照字符读while(true){char[] buffer = new char[1024];int len = reader.read(buffer);if(len == -1)break;//如果传入的是byte数组,还可以手动指定utf8字符集避免乱码String s =new String(buffer,0,len);System.out.println(s);}}catch(IOException e){e.printStackTrace();}

输出结果为:

3.4 Writer  字符流的写操作

试运行以下代码:

        try(Writer writer  = new FileWriter("./file1.txt")){writer.write("xyz");}catch(IOException e){e.printStackTrace();}

打开对应文件:

注:与FileOutputStream类似,每次读文件时文件原有内容会被清空;

4. 文件操作的应用

例1:扫描指定目录并找到名称中包含指定字符的所有普通文件(不包含目录),并且后续询问用户是否要删除该文件:

实现思路:

输入目录——>输入要删除的文件名——>询问是否要删除文件;

代码如下:

import java.io.File;
import java.io.IOException;
import java.util.Scanner;//例1: 扫描到指定目录,并找到名称中含有指定字符的所有普通文件,并且后续询问是否要删除该文件
public class Demo5{public static void main(String[] args) {System.out.println("请输入要扫描的路径:");Scanner scanner = new Scanner(System.in);String rootDirPath = scanner.next();System.out.println("请输入要删除的文件:");String toDeleteName = scanner.next();File rootDir = new File(rootDirPath);if(!rootDir.isDirectory()){System.out.println("输入的扫描路径有误!");}scanDir(rootDir,toDeleteName);}public static void scanDir(File rootDir,String toDeleteName){File[] files = rootDir.listFiles();if(files == null){System.out.println("目录为空!");return;}for(File f:files){if(f.isFile()){if(f.getName().contains(toDeleteName)){//只要文件名含有关键字即可,不要求完全相同deleteFile(f);}}else if(f.isDirectory()){scanDir(f, toDeleteName);}}}public static void deleteFile(File f){try {System.out.print(f.getCanonicalPath() + "  ");System.out.println("是否要删除该文件?(Y / N)");Scanner scanner = new Scanner(System.in);String choice = scanner.next();if (choice.equals("Y")|| choice.equals("y")) {f.delete();System.out.println("文件删除成功!");} else {System.out.println("文件删除取消!");}}catch(IOException e){e.printStackTrace();}}
}

原路径下目录及文件如下:

试运行后,输出结果为:

 根据路径查找对应文件:

例2:进行普通文件的复制

实现思路:

指定一个被复制的原文件路径与一个复制之后生成的目标文件路径。打开原路径文件读取内容后写入到目标文件;

代码如下:

import java.io.*;
import java.util.Scanner;public class Demo6{public static void main(String[] args) {//1. 输入原路径与目标路径Scanner scanner = new Scanner(System.in);System.out.println("请输入要拷贝的原文件:");String src = scanner.next();System.out.println("请输入要拷贝的目标文件:");String dest = scanner.next();File srcFile = new File(src);if(!srcFile.isFile()){System.out.println("输入的原路径有误!");return;}//无需检查目标文件是否存在,OutputStream写文件时会自动创建不存在的文件//2. 拷贝:读取原文件拷贝到目标文件try(InputStream inputStream = new FileInputStream(src)){try(OutputStream outputStream = new FileOutputStream(dest)){//将inputStream中的内容读取出来放到outputStream中byte[] buffer = new byte[1024];while(true){int len = inputStream.read(buffer);if(len==-1){//读取结束break;}//buffer中可能只有一部分是有效数据,不能全部写入outputStream.write(buffer,0,len);}}}catch(IOException e){e.printStackTrace();}}
}

试运行:

查看对应路径文件内容:

 

例3:扫描指定目录,并找到名称或内容中包含指定字符的所有普通文件:

代码如下:

import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
import java.util.Scanner;public class Demo7{public static void main(String[] args) throws IOException {//1.输入要扫描的路径Scanner scanner = new Scanner(System.in);System.out.println("请输入要扫描的路径:");String rootDirPath = scanner.next();System.out.println("请输入要查找的关键词:");String word = scanner.next();File rootDir = new File(rootDirPath);if(!rootDir.isDirectory()){System.out.println("输入的路径非法!");return;}//2.递归进行遍历scanDir(rootDir, word);}public static void scanDir(File rootDir,String word) throws IOException {//1.先列出rootDir中的内容File[] files = rootDir.listFiles();if(files == null){return;}//2.遍历每个元素,针对普通文件和目录文件分别进行处理for(File f:files){if(f.isFile()){//针对普通文件进行关键词查找if(containsWord(f, word)){System.out.println(f.getCanonicalPath());}}else if(f.isDirectory()){scanDir(f, word);}}}public static boolean containsWord(File f,String word){//将f中的内容都读出来放在一个StringBuilder中StringBuilder stringBuilder = new StringBuilder();try(Reader reader = new FileReader(f)){char[] buffer = new char[1024];while(true){int len = reader.read(buffer);if(len == -1){break;}//将此处的结果放置到StringBuilder中去stringBuilder.append(buffer, 0, len);}}catch(IOException e){e.printStackTrace();}//indexOf返回的是子串的下标,如果word在stringBuilder中不存在就返回-1return stringBuilder.indexOf(word)!=-1;}
}

原路径下目录及文件内容如下:

 试运行后,输出结果为:

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

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

相关文章

openGauss学习笔记-221 openGauss性能调优-确定性能调优范围-分析作业是否被阻塞

文章目录 openGauss学习笔记-221 openGauss性能调优-确定性能调优范围-分析作业是否被阻塞221.1 操作步骤 openGauss学习笔记-221 openGauss性能调优-确定性能调优范围-分析作业是否被阻塞 数据库系统运行时&#xff0c;在某些业务场景下查询语句会被阻塞&#xff0c;导致语句…

【MySQL】操作库 —— 表的操作 -- 详解

一、增加表 1、创建表 mysql> create database [if not exists] table_name ( -> field1 datatype, -> field2 datatype, -> field3 datatype -> ) character set 字符集 collate 校验规则 engine 存储引擎; 注意 &#xff1a;最后一行也可以写成&#x…

Vue源码系列讲解——模板编译篇【二】(整体运行流程)

目录 1. 整体流程 2. 回到源码 3. 总结 1. 整体流程 上篇文章中我们说了&#xff0c;在模板解析阶段主要做的工作是把用户在<template></template>标签内写的模板使用正则等方式解析成抽象语法树&#xff08;AST&#xff09;。而这一阶段在源码中对应解析器&…

c语言操作符(上)

目录 ​编辑 原码、反码、补码 1、正数 2、负数 3、二进制计算1-1 移位操作符 1、<<左移操作符 2、>>右移操作符 位操作符&、|、^、~ 1、&按位与 2、|按位或 3、^按位异或 特点 4、~按位取反 原码、反码、补码 1、正数 原码 反码 补码相同…

STM32 HAL库 STM32CubeMX -- IWDG(独立看门狗)

STM32 HAL库 STM32CubeMX -- IWDG 一、IWDG简介二、独立看门狗的工作原理三、驱动函数初始化函数HAL IWDG Init()初始化函数HAL IWDG Init()其他宏函数 四、超时时间计算第一种办法第二种办法&#xff08;推荐&#xff09; 一、IWDG简介 看门狗(Watchdog)就是MCU上的一种特殊的…

【AIGC】Stable Diffusion的模型入门

下载好相关模型文件后&#xff0c;直接放入Stable Diffusion相关目录即可使用&#xff0c;Stable Diffusion 模型就是我们日常所说的大模型&#xff0c;下载后放入**\webui\models\Stable-diffusion**目录&#xff0c;界面上就会展示相应的模型选项&#xff0c;如下图所示。作者…

计算机网络——多媒体网络

前些天发现了一个巨牛的人工智能学习网站 通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家&#xff0c; 跳转到网站 小程一言 我的计算机网络专栏&#xff0c;是自己在计算机网络学习过程中的学习笔记与心得&#xff0c;在参考相关教材&#xff0c;网络搜素…

保育员考试怎么搜题找答案?9个不限次的公众号和软件分享啦! #经验分享#学习方法

学会运用各类学习辅助工具和资料&#xff0c;是大学生培养自主学习能力和信息获取能力的重要途径之一。 1.粉鹿搜题 这是一个公众号 使用方法也很简单&#xff0c;将题目发送至公众号后台&#xff0c;即可得到题目答案~ 下方附上一些测试的试题及答案 1、下列哪项是聚合式联…

DS Wannabe之5-AM Project: DS 30day int prep day18

Q1. What is Levenshtein Algorithm? Levenshtein算法&#xff0c;也称为编辑距离算法&#xff0c;是一种量化两个字符串之间差异的方法。它通过计算将一个字符串转换成另一个字符串所需的最少单字符编辑操作次数来实现。这些编辑操作包括插入、删除和替换字符。Levenshtein距…

掌握Go并发:Go语言并发编程深度解析

&#x1f3f7;️个人主页&#xff1a;鼠鼠我捏&#xff0c;要死了捏的主页 &#x1f3f7;️系列专栏&#xff1a;Golang全栈-专栏 &#x1f3f7;️个人学习笔记&#xff0c;若有缺误&#xff0c;欢迎评论区指正 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&…

第三讲 数据存储

面向磁盘的架构 DBMS 假定数据库的主要存储位置位于非易失性磁盘【non-volatile disk】上。 DBMS 的组件管理非易失性【non-volatile】和易失性【volatile】存储之间的数据移动。 为了理解来回移动数据的影响&#xff0c;我们首先要先理解存储层次结构是什么样的。 存储层次【…

文生图提示词:气候特征

天气和气候 --气候特征 Climate Features 气候特征的基本词汇&#xff0c;涵盖了温度和湿度的变化&#xff0c;以及它们在不同气候类型中的体现。 Hot 炎热 Cold 寒冷 Warm 温暖 Cool 凉爽 Humid 湿润 Dry 干燥 Mild 温和 Chilly 冷飕飕 Freezing 冰冻 Sweltering 酷热 Frosty …

RK3568平台开发系列讲解(实验篇)杂项设备驱动实验

🚀返回专栏总目录 文章目录 一、什么是杂项设备驱动二、杂项设备的注册和卸载三、杂项设备驱动实验代码沉淀、分享、成长,让自己和他人都能有所收获!😄 一、什么是杂项设备驱动 在 Linux 中,把无法归类的五花八门的设备定义成杂项设备。相较于字符设备,杂项设备有以下两…

企业数字化转型战略规划与实践:迈向未来的关键之举

在信息技术的不断革新和全球数字化浪潮的推动下&#xff0c;企业数字化转型已经成为当今商业世界中不可或缺的一项战略规划。随着技术的进步&#xff0c;企业必须积极应对数字化转型的挑战&#xff0c;并将其作为发展的关键驱动力。本文将探讨企业数字化转型的重要性&#xff0…

幻兽帕鲁联机服务器搭建新手小白教程

这里分为两种搭建方式&#xff0c;都是采用的一键搭建的傻瓜式教程&#xff0c;1分钟就可以搞定。 一、通过阿里云一键部署幻兽帕鲁服务器 以下教程基于阿里云服务器来搭建幻兽帕鲁游戏服务器&#xff0c;通过一键部署的方式&#xff0c;最快1分钟即可完成部署。 阿里云一键…

【白话前端】一篇文章区分js库和js框架

假定你选择自助游&#xff0c;你需要找不同服务商帮你解决吃住行的问题&#xff0c;这些服务商就是js库。你也可以选择旅行社&#xff0c;给你全解决&#xff0c;这是js框架。 JavaScript库和框架都是用于简化Web开发的工具&#xff0c;但它们之间有一些区别。 JavaScript库&a…

【Java多线程】Thread类的基本用法

目录 Thread类 1、创建线程 1.1、继承 Thread&#xff0c;重写run 1.2、实现 Runnable&#xff0c;重写run 1.3、使用匿名内部类&#xff0c;继承 Thread&#xff0c;重写run 1.4、使用匿名内部类&#xff0c;实现 Runnable&#xff0c;重写run 1.5、使用 lambda 表达式…

Swift Combine 级联多个 UI 更新,包括网络请求 从入门到精通十六

Combine 系列 Swift Combine 从入门到精通一Swift Combine 发布者订阅者操作者 从入门到精通二Swift Combine 管道 从入门到精通三Swift Combine 发布者publisher的生命周期 从入门到精通四Swift Combine 操作符operations和Subjects发布者的生命周期 从入门到精通五Swift Com…

KMS知识管理系统:一文扫盲,体验为王,落地为皇

知识管理系统是学习型组织的必备&#xff0c;重要性不言而喻&#xff0c;但是往往在执行中不能落地&#xff0c;本位尝试做些KMS的扫盲。 一、KMS是什么 知识管理系统&#xff08;英语&#xff1a;Knowledge management system&#xff09;是一种用于管理和共享企业内部知识的…

如何为你的幻兽帕鲁服务器手动配置虚拟内存或Swap、Zram

其实非常简单&#xff0c;如果是Windows系统服务器的话&#xff0c;直接远程连接到服务器桌面。 连上之后&#xff0c;打开设置&#xff0c;找到“高级系统设置” 可以参考视频教程&#xff1a; 拒绝卡顿&#xff01;幻兽帕鲁服务器内存优化攻略&#xff01; 详细教程地址&…