文件操作 -- IO
文章目录
- 文件操作 -- IO
- 文件 :
- 文件路径 :
- 文件的类型
- java 中的文件操作
- 文件内容的相关操作
- 字节流的读和写操作
- 字符流的读和写操作
- 代码案例
- 代码案例一 :
- 代码案例二 :
- 代码案例三 :
文件操作 – IO
文件 :
文件相比大家都不陌生把 , 打开我们的电脑,随便进入到一个盘内,都能看到一些文件, 比如 : txt 文本, jpg 图片, mp4视频 ,还有文件夹(专业一点称为目录) 这些都是文件 .
但是 文件(File) 这个概念 在计算机里 , 也是 “一词多用” 。
正因如此 我们将上面这些文件都认为是狭义的文件 ,特点就是存储在硬盘上。
而广义的文件 : 泛指计算机中很多的 软硬件资源 , 操作系统中,把很多的硬件设备和软件资源抽象成了 文件 ,按照文件的方式来统一管理.
后面学习的网络编程中 就会讲到一个很重要的设备 网卡 , 网卡 是一个硬件设备,但是在操作系统中就把网卡这样的硬件给抽象成了一个文件 。
为啥这样做呢 ?
因为这样的操作 ,可以让我们进行网络编程带来很大的便利, 比如 我们想要通过网卡接收数据,直接按照读文件代码去写就可以了 , 想要进行网卡来发送数据,直接按照写文件的代码 去写即可,这里就可以通过对文件的操作来完成对网卡的操作,简化了开发。
本文只讨论狭义的文件 , 也就是硬盘上的数据.
文件路径 :
之前我们写过的代码,存储的数据,主要是靠变量, 而变量是存储在内存中,关闭程序后这些变量就会释放,啥都没有留下,而现在我们学习的文件是保存在硬盘上的,既然保存在硬盘上,那么文件都会有属于自己的路径
知道了 路径,下面来 了解一下路径的两种表示风格
1.绝对路径 : 以盘符开头的路径
2.相对路径 : 以当前所在的目录为基准 , 以 .
或者 ..
开头 (.有时候可以省略) , 找到指定的路径
相对路径图解 :
相对路径看完, 下面来了解一下 文件的类型。
文件的类型
我们的文件有 word , exe , 图片 ,视频 , 音频 , 源代码 , 动态库 等 ,这些不同的文件, 整体 可以归纳到 两类中 。
1.文本文件 (存的是文本, 字符串)
这里字符串 , 是由字符构成的, 每个字符,都是通过一个数字来表示的, 这里文本文件,里存的数据,一定是合法的字符, 都是再你指定字符编码表之内的数据
2.二进制文件 (存的是二进制数据,不一定是字符串了)
二进制文件中 数据就没有任何限制,可以存储任何你想要的数据。
那么这里就有一个问题 ,随便给你一个文件,如何区分该文件是文本还是二进制文件呢?
其实很简单,这里直接拿记事本打开 这个文件,如果乱码就说明是二进制文件,反之就是文本文件 。
注意 : 实际写代码 的时候,这两类文件的处理方式略有区别.
了解完上面这些背景知识, 下面就来了解一下 java 对于 文件的操作 .
java 中的文件操作
这里我们主要针对两方面 :
1.针对文件系统操作 , (文件的创建, 删除, 重命名 等)
2.针对文件内容操作 (文件的读和写操作)
下面继续 , 在 java 标准库中提供了一个 File类,这个 File 类就描述了一个文件/目录 , 基于这个对象就可以实现上面这两方面.
注意, 有File 对象,并不代表真实存在该文件
下面来看看 File 类 的属性和构造方法
File 类的属性
修饰符及类型 | 属性 | 说明 |
---|---|---|
static String | pathSeparator | 依赖于系统的路径分隔符(分隔符就是 / 或者 \ ) String 类型的表示 |
static char | pathSeparator | 依赖于系统的路径分隔符,char 类型的表示 |
File 类的构造方法
签名 | 说明 |
---|---|
File(File parent, String child) | 根据父目录 + 孩子文件路径,创建一个新的 File 实例 |
File(String pathname) | 根据文件路径创建一个新的 File 实例,路径可以是绝对路径或者相对路径 |
File(String parent, String child) | 根据父目录 + 孩子文件路径,创建一个新的 File 实例,父目录用路径表示 |
上面这些指定的路径参数,可以是绝对路径也可以是相对路径.
parent 表示当前文件所在的目录
child 自身的文件名
在 new File 对象的时候, 在构造方法的参数中,可以指定一个路径,此时File对象就代表 这个路径对应的文件了。
File 类的方法
修饰符及返回值类型 | 方法签名 | 说明 |
---|---|---|
String | getParent() | 返回 File 对象的父目录文件路径 |
String | getName() | 返回 FIle 对象的纯文件名称 |
String | getPath() | 返回 File 对象的文件路径 |
String | getAbsolutePath() | 返回 File 对象的绝对路径 |
String | getCanonicalPath() | 返回 File 对象的修饰过的绝对路径 |
boolean | exists() | 判断 File 对象描述的文件是否真实存在 |
boolean | isDirectory() | 判断 File 对象代表的文件是否是一个目录 |
boolean | isFile() | 判断 File 对象代表的文件是否是一个普通文件 |
boolean | createNewFile() | 根据 File 对象,自动创建一个空文件。成功创建后返回 true |
boolean | delete() | 根据 File 对象,删除该文件。成功删除后返回 true |
void | deleteOnExit() | 根据 File 对象,标注文件将被删除,删除动作会到。JVM 运行结束时才会进行 |
String[] | list() | 返回 File 对象代表的目录下的所有文件名 |
File[] | listFiles() | 返回 File 对象代表的目录下的所有文件,以 File 对象表示 |
boolean | mkdir() | 创建 File 对象代表的目录 |
boolean | mkdirs() | 创建 File 对象代表的目录,如果必要,会创建中间目录 |
boolean | renameTo(Filedest) | 进行文件改名,也可以视为我们平时的剪切、粘贴操作 |
boolean | canRead() | 判断用户是否对文件有可读权限 |
boolean | canWrite() | 判断用户是否对文件有可写权限 |
别被这些方法吓到了, 不用背,用到的时候,查一下即可,下面就来使用几个方法 。
File 类的使用
图一 :
图二 : 相对路径
下面继续 :
这里来看三个比较实用的
1.判断文件是否真实存在 : exists()
2.判断文件是否是一个普通文件 : isFile()
3.判断文件是否是一个目录 : isDirectory()
可以看到我们再绝对路径下,使用这几个方法结果都是false , 表示在d盘下没有test.txt 这个文件,下面就来学习一下如何创建文件
这里需要使用 File 类 提供的方法 : createNewFile
既然有创建文件的方法,那么肯定有删除文件的方法 ,下面就来使用一下 delete 方法
关于删除文件的方法还有一个方法 : deleteOnExit ()
使用 deleteOnExit () 方法, 会在程序退出的时候,自动删除.
使用场景 : 程序中需要使用到一些 “临时文件” 的时候 ,就需要用到。
举个例子 :
了解完删除方法, 下面我们来创建一个目录 。
创建目录 : mkdir()
注意 : 这里的 mkdir方法只能创建 一级目录,如果想要创建多级目录 需要使用 mkdirs 方法
创建多级目录方法 : mkdirs ()
创建目录看完,下面使用 ,重命名方法 : renameTo ()
演示 :
重命名看完,下面来看看 list 、listFiles
这两个方法
list () : 返回 File 对象代表的目录下的所有文件名
返回 File 对象代表的目录下的所有文件,以 File 对象表示
演示 :
图二 :
到此 文件操作的相关方法差不多就看完了, 下面来学习一下, 关于 文件内容相关的操作
文件内容的相关操作
这里针对文件内容 ,使用 “流对象” 进行操作 .
解释一下 啥叫流 :
这里的流对象 是形象的比喻 , 在计算机里的很多概念,都使用了一定的修辞手法 .
这里的比喻就是一种常见的方法 .
另外 : 使用一个链表头节点/二叉树根节点,表示整个链表/二叉树 , 这也是一个修辞手法 。
此时使用的就是借代(局部表示整体),借代也是一种常见的修辞手法
下面继续
谈到流 这里第一印象 就是 水流 特点:生生不息 ,绵延不断 , 这里的流对象就是这样的 。
这里就可以想象一个 场景 :有一个水龙头 ,想要通过这个水龙头 可以接水 ,
假设 需要接100ml 的水 ,
这里就可以采用 一次接 100ml , 一次接完 , 也可以 一次接 50ml 分两次接 ,还可以一次接 10ml 分 10次 … 。
关于这里的装水,我们就可以随心所欲的安排 一次装多少水 ,只需要保证最终接收到 100ml 的水
这就是 流的一个特点 : 可以随心所欲的调整接收的数据量
对比一下 其他固体 的东西, 比如 体育室 里面的 篮球,这里就只能一个一个的拿, 能 一次性拿1.5 个吗显然是不可以的 ,这里就不是流 。
我们想要从文件读一百个字节
1.可以 一次 读 100个字节, 分一次读完
2.可以 一次 读 50个字节,分两次 读完
3.可以 一次 读 10个字节,分十次 读
…
这里我们读文件操作是不是就和 水流接水的操作相似 , 写文件同理 ,因此就把读写文件的相关操作称为 “流对象”
附上一张图:
知道了啥是流 , 下面来看看 java 标准库的流对象 .
这里从类型上,分为两个大类
1.字节流
字节流 : 针对二进制文件 ,以字节为单位进行读写
读相关的类
InputStream 抽象类
, FileInputStream 对应子类
写相关的类
OutputStream 抽象类
, FileOutPutStream 对应的子类
2.字符流
字符流 : 针对文本文件 , 以字符为单位进行读写
读相关的类
Reader 抽象类
, FileReader 对应的子类
写相关的类
Writer 抽象类
, FileWriter 对应的子类
别看这里的类很多,其实这里的类使用方式是非常固定的
核心就四个操作
1.打开文件. (构造对象)
2.关闭文件. (close)
3.读文件 . (read) --> 针对 InputStream / Reader
4.写文件 .(write) --> 针对 OutputStream / Write
说了这么多,下面来写个代码演示一下如何使用 .
字节流的读和写操作
读文件 : InputStream
图一 :
图二 : 带有一个参数版本的 read
这里输出型参数 ,就好比食堂打饭,将餐盘给 食堂阿姨,阿姨给你打饭 ,打完饭再将 餐盘还给你 .
这里 read 带有三个参数版本的 与 带有一个版本的类似 简单演示一下
buffer 名词解释 :
这里可以想象成 嗑瓜子 , 没有使用 缓冲区(buffer) , 磕一个瓜子 , 抛一次壳 (进行一次 IO 操作) , 这样嗑瓜子明显就非常麻烦 , 将我们的 手看成一个缓冲区, 当我们磕满一个手的瓜子壳 (此时相当于进行了一次IO操作, 读取了一个数组长度的数据 ),再去抛壳,是不是 效率就高了。。
读文件看完 , 下面瞧瞧写文件
写文件 :OutputStream
图一 :
有没有好奇,为啥 input 是读操作 , 而 output 是写操作 , input 翻译过来是 输入的意思 output 翻译过来是 输出的意思,那么为啥 输入不是写操作而是读操作呢 ?
关于这个问题 : 这里就需要注意 input 和 output 的方向,z这里的方向是以 CPU 为中心 进行看待的 ,
下面来看一个比较重要的东西 .
图一 :
图二 :
到此 字节流 的 读和写操作 就看完了, 下面来 简单 演示一下 字符流的读和写操作 (因为这些类的用法都一样)
字符流的读和写操作
1.字符流 读操作
2.写操作
补充 :flsush 方法 手动刷新缓冲区
上面 解释名词 buffer ,了解了一下缓冲区 ,并且知道了缓冲区存在的意义就是为了提高效率 .
下面就针对缓冲区 补充一个方法 flush , 这个方法是用来刷新缓冲区的 。
比如 : 在写数据的时候,需要把数据写到缓冲区里,然后再统一写入到硬盘, 如果当前的缓冲区已经写满了,就直接触发写硬盘操作,如果当前的缓冲区还没写满,如果 想提前将数据写入到硬盘里,这时就可以通过 flush 来手动 刷新缓冲区 .
之前 的代码 ,没有涉及到 flush , 是因为 代码并没有涉及到很多数据,很快执行完了 try 语句,而 try 语句结束的时候,会自动调用 close 方法 进行释放文件对象,关闭文件, 此时close 就会刷新缓冲区 。
再来补充一点 :Scanner 可以搭配流对象进行使用
此时 使用 scanner 读取 一个文件,就比较方便了 ,
最后再来补充一个 :使用 PrintWriter 类 进行写操作
PrintWriter 类 提供了 我熟悉的 print , printf , println 方法,方便我们进行写操作
此时关于文件内容就看完了,主要就是那几个类 , 下面就写几个关于文件的代码案例来熟悉一下 这些 API 。
代码案例
代码案例一 :
案例1:扫描指定目录,并找到名称中包含指定字符的所有普通文件(不包含目录),并且后续询问用户是否要删除该文件
这里会先 给顶一个目录, 目录里会包含很多的文件和子目录…
用户输入一个要查询的词 ,看看当前目录下(以及子目录里) 是否有匹配的结果 (文件名匹配) , 如果有匹配的结果,就进行删除
import java.io.File;
import java.util.Scanner;public class Test4 {private static Scanner scanner = new Scanner(System.in);public static void main(String[] args) {// 让用户输入一个指定搜索的目录Scanner scanner = new Scanner(System.in);System.out.println("请输入要搜索的路径: ");String basePath = scanner.next();// 针对用户输入进行简单判定File root = new File(basePath);// isDirectory() 判断当前的文件是否为目录文件if (!root.isDirectory()) {// 路径 不纯在, 或者知识一个普通的文件, 此时无法进行搜索System.out.println("输入的目录有误!");return;}// 前面没问题 此时再让用户输入一个 要删除的文件名System.out.println("请输入要删除的文件名: ");// 此处要使用 next , 而不要使用 nextLine !!!String nameToDelete = scanner.next();// 针对指定的路径进行扫描 , 这里就可以采用递归操作// 先从我们的 根目录触发 (root)// 先判定一下 , 当前的这个目录 ,是否包含要删除的文件,如果是就删除 ,否则就跳过下一个// 如果当前这里包含了一些目录 ,再针对子目录进行递归.scanDir(root, nameToDelete);}private static void scanDir(File root, String nameToDelete) {// 1. 先列除当前路径下包含的内容File[] files = root.listFiles();if (files == null) {// 当前 root 目录下没东西 , 是一个空目录// 此时就结束继续递归return;}// 2. 遍历当前的列出结果for (File f : files) {if (f.isDirectory()) {// 如果是目录就进一步 递归scanDir(f, nameToDelete);} else {// 如果是普通文件,则判定是否要删除if (f.getName().contains(nameToDelete)) {// 这里可以再判断一下System.out.println("确认是否要删除 " + f.getAbsolutePath() + " 吗?");String choice = scanner.next();if (choice.equals("y") || choice.equals("Y")) {f.delete();System.out.println("删除成功!");} else {System.out.println("删除取消!");}}}}}}
代码案例二 :
案例二 : 普通文件的复制
要求 : 把一个文件拷贝成另一个文件.
这里就非常简单, 就是把第一个文件按照字节依次读取,把结果写到另一个文件中 .
import java.io.*;
import java.util.Scanner;public class Test5 {public static void main(String[] args) {// 输入两个路径.// 源 和 目标 . (从那里拷贝到哪里)Scanner scanner = new Scanner(System.in);System.out.println("请输入要拷贝那个文件: ");String srcPath = scanner.next();System.out.println("请输入要被拷贝到那个地方: ");String destPath = scanner.next();File srcFile = new File(srcPath);if (!srcFile.isFile()) {// 如果 源 不是一个文件(不存在或者是目录) ,此时不做任何操作System.out.println("您当前输入的源路径有误");}File destFile = new File(destPath);if (destFile.isFile()) {// 如果已近存在 认为也不能拷贝 (比如说拷贝后的名字叫 坤.txt , 但是 目标目录下已经存在 坤.txt 此时拷贝相当于覆盖掉原来的文件)System.out.println("您当前输入的目标路径有误!");return;}//
// if (destFile.exists()) {
//
// if (destFile.isDirectory()) {
// System.out.println("目标路径已存在 ,并且是一个目录,请确认路径是否正确");
// return;
// }
//
// if (destFile.isFile()) {
// System.out.println("目录路径已经存在,是否要进行覆盖? 覆盖 输入 y");
// String ret = scanner.next();
//
// if (!ret.toLowerCase().equals("y")) {
// System.out.println("停止覆盖");
// return;
// }
//
// }
// }// try(InputStream inputStream = new FileInputStream(srcFile)){
//
// try(OutputStream outputStream = new FileOutputStream(destFile)){
//
// }
//
// }catch (IOException e){
// e.printStackTrace();
// }// 进行拷贝操作try (InputStream inputStream = new FileInputStream(srcFile);OutputStream outputStream = new FileOutputStream(destFile)) {// 进行读文件操作.while (true) {byte[] buffer = new byte[1024];int len = inputStream.read(buffer);if (len == -1) {break;}outputStream.write(buffer);}} catch (IOException e) {e.printStackTrace();}}
}
代码案例三 :
案例三 : 扫描指定目录 , 并找到名称或者内容中包含指定字符的所有普通文件 (不包含目录)
这里就是进行文件内容的查找
主要分为三步骤
1.输入一个路径
2.在输入一个要查找文件的关键字
3.递归的遍历文件 , 找到含有关键字的文件,将对应的文件路径打印出来。
其实 这个代码案例 就与第一个代码案例非常相似 .
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
import java.util.Scanner;public class Test6 {public static void main(String[] args) {Scanner sc = new Scanner(System.in);System.out.print("输入要扫描的路径: ");String rootDirectoryPath = sc.next();// 换一行System.out.println();System.out.print("输入要查询的文件名关键字: ");String keyword = sc.next();System.out.println();File file = new File(rootDirectoryPath);if (!file.isDirectory()) {// 此时不是目录文件, 表示当前的路径有误System.out.println("输入的路径错误! ");return;}// 进行递归遍历scannerDirectory(file, keyword);}private static void scannerDirectory(File file, String keyword) {// 1. 先列出 file 中 有那些内容File[] files = file.listFiles();if (files == null) {return;}for (File f : files) {if (f.isFile()) {// 此时 f 是普通的文件 ,// 针对普通文件的内容 进行判断 , 是否满足查询条件 (文件内容是否包含 关键字 keyword)if (containsKeyword(f, keyword)) {// 此时普通文件中 含有我们需要查询的关键字, 将路径打印出来System.out.println(f.getAbsolutePath());}} else if (f.isDirectory()) {// 此时 f 为目录文件,那么进入 目录 文件, 然后继续递归查找scannerDirectory(f, keyword);}}}private static boolean containsKeyword(File f, String keyword) {// 将 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 返回的是子串 (keyword) 的下标 , 如果 word 在StringBuilder 中不存在 ,则返回 -1return stringBuilder.indexOf(keyword) != -1;}
}
图示 :
小补充一点 : OutputStream 在写文件的时候,文件不存在 就会自动创建, InputStream 不行, 文件不存在,就抛异常了
到此 文件操作 就结束了, 比较简单, 就是一些 API 的使用 。
相关文章:

文件操作 -- IO
文章目录文件操作 -- IO文件 :文件路径 :文件的类型java 中的文件操作文件内容的相关操作字节流的读和写操作字符流的读和写操作代码案例代码案例一 :代码案例二 :代码案例三 :文件操作 – IO 文件 : 文件相比大家都不陌生把 , 打…...

FPGA解析串口协议帧3.0版本,增加了错误重发功能,提供仿真文件以及源码
FPGA解析串口协议帧已经发布2个版本了,分别如下: 版本1:点击查看版本1 版本1详细介绍了串口协议帧的帧组成和设计思想,但设计粗糙,注释不详细; 版本1:点击查看版本2 版本2优化了代码,…...

365天深度学习训练营 第P6周:好莱坞明星识别
🍨 本文为🔗365天深度学习训练营 内部限免文章(版权归 K同学啊 所有)🍦 参考文章地址: 🔗第P6周:好莱坞明星识别 | 365天深度学习训练营🍖 作者:K同学啊 | 接…...

一文读懂 Zebec Chain 的“先行网络” Nautilus 链
最近,Zebec 上线了 DAO 治理系统后,上线并通过了关于 Nautilus 链的提案,这也是DAO系统上线后通过的首个提案。 Nautilus 链可以被看作是Zebec Chain上线前的“先行”链,并且是目前行业内为数不多的以“Layer3”作为特点的模块化通…...
FuzzyMathematicalModel模糊数学模型-2-多目标模糊综合评价案例分享
主函数:clc, clear% 输入模糊矩阵的原型x [4700 6700 5900 8800 76005000 5500 5300 6800 600004.0 06.1 05.5 07.0 06.80030 0050 0040 0200 01601500 0700 1000 0050 0100];r muti_objective_fuzzy_analysis(x);% 各指标在决策中占的权重(专家系统,自…...

单链表--C语言版(从0开始,超详细解析,小白一看就会)
目录 一、前言 🍎 为什么要学习链表 💦顺序表有缺陷 💦 优化方案:链表 二、链表详解 🍐链表的概念 🍉链表的结构组成:节点 🍓链表节点的连接(逻辑结构与物理结构的区…...
cv2-特征点匹配(bf、FLANN)
cv2-特征点匹配(bf、KNN、FLANN) 文章目录cv2-特征点匹配(bf、KNN、FLANN)1. 暴力匹配法(bf)1.1 bf.match()1.2 bf.knnMatch()3. FLANN匹配法4. 总结1. 暴力匹配法(bf) (…...

基于matlab多功能相控阵雷达资源管理的服务质量优化
一、前言此示例说明如何为基于服务质量 (QoS) 优化的多功能相控阵雷达 (MPAR) 监控设置资源管理方案。它首先定义必须同时调查的多个搜索扇区的参数。然后,它介绍了累积检测范围作为搜索质量的度量,并展示了…...

立创eda专业版学习笔记(6)(pcb板移动节点)
先要看一个设置方面的东西: 进入设置-pcb-通用 我鼠标放到竖着的线上面,第一次点左键是这样选中的: 再点一次左键是这样选中的: 这个时候,把鼠标放到转角的地方,点右键,就会出现对于节点的选项…...

Java面试——MyBatis相关知识
目录 1.什么是MyBatis 2.MyBatis优缺点 3.MyBatis工作原理 4.MyBatis缓存模式 5.MyBatis代码相关问题 6.MyBatis和hibernate区别 1.什么是MyBatis MyBatis是一个半ORM持久层框架(对象关系映射),基于JDBC进行封装,使得开发者…...

Cortex-M0编程入门
目录1.嵌入式系统编程入门微控制器是如何启动的嵌入式程序设计2.输入和输出3.开发流程4.C编程和汇编编程5.什么是程序映像6.C编程:数据类型7.用C语言操作外设8.Cortex微控制器软件接口标准(CMSIS)简介标准化内容组织结构使用方法优势1.嵌入式…...

字符串函数能有什么坏心思?
🚀write in front🚀 📝个人主页:认真写博客的夏目浅石. 🎁欢迎各位→点赞👍 收藏⭐️ 留言📝 📣系列专栏:夏目的C语言宝藏 💬总结:希望你看完之…...

Vue3 组件之间的通信
组件之间的通信 经过前面几章的阅读,相信开发者已经可以搭建一个基础的 Vue 3 项目了! 但实际业务开发过程中,还会遇到一些组件之间的通信问题,父子组件通信、兄弟组件通信、爷孙组件通信,还有一些全局通信的场景。 …...

多路查找树
1.二叉树与 B 树 1.1二叉树的问题分析 二叉树的操作效率较高,但是也存在问题, 请看下面的二叉树 二叉树需要加载到内存的,如果二叉树的节点少,没有什么问题,但是如果二叉树的节点很多(比如 1 亿), 就 存在如下问题:问…...
Mybatis——注入执行sql查询、更新、新增以及建表语句
文章目录前言案例dao和mapper编写XXXmapper.xml编写编写业务层代码,进行注入调用额外扩展--创建表语句前言 在平时的项目开发中,mybatis应用非常广泛,但一般都是直接CRUD类型sql的执行。 本片博客主要说明一个另类的操作,注入sq…...

即时通讯系列-4-如何设计写扩散下的同步协议方案
1. 背景信息 上篇提到了, IM协议层是主要解决会话和消息的同步, 在实现上, 以推模式为主, 拉模式为辅. 本文Agenda: (How)如何同步(How)如何设计同步位点如何设计 Gap过大(SyncGapOverflow) 机制如何设计Ack机制总结 提示: 本系列文章不会单纯的给出结论, 希望能够分享的是&…...

tui-swipe-action组件上的按钮点击后有阴影的解决方法
大家好,我是雄雄,欢迎关注微信公众号:雄雄的小课堂。 目录 前言问题描述问题解决前言 一直未敢涉足电商领域,总觉得这里面的道道很多,又是支付、又是物流的,还涉及到金钱,所以我们所做的项目,一直都是XXXX管理系统,XXX考核系统,移动端的也是,XX健康管理平台…… 但…...

【大数据Hadoop】Hadoop 3.x 新特性总览
Hadoop 3.x 新特性剖析系列11. 概述2. 内容2.1 JDK2.2 EC技术2.3 YARN的时间线V.2服务2.3.1 伸缩性2.3.2 可用性2.3.3 架构体系2.4 优化Hadoop Shell脚本2.5 重构Hadoop Client Jar包2.6 支持等待容器和分布式调度2.7 支持多个NameNode节点2.8 默认的服务端口被修改2.9 支持文件…...

Python-第三天 Python判断语句
Python-第三天 Python判断语句一、 布尔类型和比较运算符1.布尔类型2.比较运算符二、if语句的基本格式1.if 判断语句语法2.案例三、 if else 语句1.语法2.案例四 if elif else语句1.语法五、判断语句的嵌套1.语法六、实战案例一、 布尔类型和比较运算符 1.布尔类型 布尔&…...

失手删表删库,赶紧跑路?!
在数据资源日益宝贵的数字时代公司最怕什么?人还在,库没了是粮库、车库,还是小金库?实际上,这里的“库”是指的数据库Ta是公司各类信息的保险柜小到企业官网和客户信息大到金融机构的资产数据和国家秘密即便没有跟数据…...

超短脉冲激光自聚焦效应
前言与目录 强激光引起自聚焦效应机理 超短脉冲激光在脆性材料内部加工时引起的自聚焦效应,这是一种非线性光学现象,主要涉及光学克尔效应和材料的非线性光学特性。 自聚焦效应可以产生局部的强光场,对材料产生非线性响应,可能…...

简易版抽奖活动的设计技术方案
1.前言 本技术方案旨在设计一套完整且可靠的抽奖活动逻辑,确保抽奖活动能够公平、公正、公开地进行,同时满足高并发访问、数据安全存储与高效处理等需求,为用户提供流畅的抽奖体验,助力业务顺利开展。本方案将涵盖抽奖活动的整体架构设计、核心流程逻辑、关键功能实现以及…...
day52 ResNet18 CBAM
在深度学习的旅程中,我们不断探索如何提升模型的性能。今天,我将分享我在 ResNet18 模型中插入 CBAM(Convolutional Block Attention Module)模块,并采用分阶段微调策略的实践过程。通过这个过程,我不仅提升…...

【入坑系列】TiDB 强制索引在不同库下不生效问题
文章目录 背景SQL 优化情况线上SQL运行情况分析怀疑1:执行计划绑定问题?尝试:SHOW WARNINGS 查看警告探索 TiDB 的 USE_INDEX 写法Hint 不生效问题排查解决参考背景 项目中使用 TiDB 数据库,并对 SQL 进行优化了,添加了强制索引。 UAT 环境已经生效,但 PROD 环境强制索…...

(二)原型模式
原型的功能是将一个已经存在的对象作为源目标,其余对象都是通过这个源目标创建。发挥复制的作用就是原型模式的核心思想。 一、源型模式的定义 原型模式是指第二次创建对象可以通过复制已经存在的原型对象来实现,忽略对象创建过程中的其它细节。 📌 核心特点: 避免重复初…...

P3 QT项目----记事本(3.8)
3.8 记事本项目总结 项目源码 1.main.cpp #include "widget.h" #include <QApplication> int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();return a.exec(); } 2.widget.cpp #include "widget.h" #include &q…...
CRMEB 框架中 PHP 上传扩展开发:涵盖本地上传及阿里云 OSS、腾讯云 COS、七牛云
目前已有本地上传、阿里云OSS上传、腾讯云COS上传、七牛云上传扩展 扩展入口文件 文件目录 crmeb\services\upload\Upload.php namespace crmeb\services\upload;use crmeb\basic\BaseManager; use think\facade\Config;/*** Class Upload* package crmeb\services\upload* …...
精益数据分析(97/126):邮件营销与用户参与度的关键指标优化指南
精益数据分析(97/126):邮件营销与用户参与度的关键指标优化指南 在数字化营销时代,邮件列表效度、用户参与度和网站性能等指标往往决定着创业公司的增长成败。今天,我们将深入解析邮件打开率、网站可用性、页面参与时…...
【生成模型】视频生成论文调研
工作清单 上游应用方向:控制、速度、时长、高动态、多主体驱动 类型工作基础模型WAN / WAN-VACE / HunyuanVideo控制条件轨迹控制ATI~镜头控制ReCamMaster~多主体驱动Phantom~音频驱动Let Them Talk: Audio-Driven Multi-Person Conversational Video Generation速…...

论文阅读笔记——Muffin: Testing Deep Learning Libraries via Neural Architecture Fuzzing
Muffin 论文 现有方法 CRADLE 和 LEMON,依赖模型推理阶段输出进行差分测试,但在训练阶段是不可行的,因为训练阶段直到最后才有固定输出,中间过程是不断变化的。API 库覆盖低,因为各个 API 都是在各种具体场景下使用。…...