新手c语言讲解及题目分享(十六)--文件系统专项练习
在我刚开始学习c语言的时候就跳过了这一章节,但在后面慢慢发现这一章节还是比较重要的,如果你报考了计算机二级c语言的话,你应该可以看到后面的三个大题有时会涉及到这章。所以说这章还是非常重要的。
目录
前言
一.打开文件
1.Fopen( )函数返回值
2.文件打开方式
二.关闭文件
三.以字符形式读写文件
1.Fgetc( )
2.Fputc( )
四.以字符串形式读写文件
1.fgets( )
2.fputs( )
五.以数据块形式读写文件
六.格式化读写文件
七.随机读写文件
八.题目分享
1.复制文件内容
2.统计文件中的字符数
3.列出目录中的所有文件
4.读取并显示文件内容
5.向文件中追加内容
6.创建新文件并写入数据
7.按行读取文件内容
8.删除文件中的特定行
9.文件重命名
10.文件大小
11.查找文件
前言
C 语言对文件有打开文件、读取和添加数据、插入和删除数据、关闭文件、删除文件等 操作。 与其他编程语言相比,C 语言文件操作的接口简单易学。在 C 语言中,为了统一对各种 硬件的操作,简化接口,不同的硬件设备也都被看成一个文件,其操作方法与普通文件的操 作方法类似。
废话不多说,直接开始正题。
一.打开文件
使用 头文件中的 fopen() 函数即可打开文件,它的用法为:
FILE *fopen(char *filename, char *mode);
filename 为文件名(包括文件路径),mode 为打开方式,它们都是字符串。
1.Fopen( )函数返回值
fopen 函数的返回值为 FILE 类型指针。如我们可以建立一个 FILE 型指针变量来存储 fopen 函数的返回值:
FILE *fp = fopen("aaa.txt","r");
上面语句作用为用只读的方式打开文件 aaa.txt 并用 fp 指向该文件,以后就可以直接通过 操作 fp 来操作文件,fp 也称文件指针。
如果文件打开失败,fopen( )函数的返回值为 NULL
2.文件打开方式
打开方式 | 说明 |
r | 只读方式打开文件,只能读文件的内容,不能写入,文件必须存在 |
w | 以写入方式打开文件,只允许写操作。文件不存在,则新建文件;若文件存在,则覆盖写入 |
a | 追加方式打开文件,在文件末尾写入数据。若文件不存在,则新建文件;若文件存在,则追加在文件末尾写入 (文件原内容保留) |
r+ | 读写方式打开文件,但文件必须存在,否则打开文件失败。 |
w+ | 相当于 w 和 r+两者叠加,既可读也可写。若文件存在,则清空文件内容写入;若不存在则创建新文件 |
a+ | 相当于 a 和 r+两者叠加,既可读也可写。若文件存在,则文件尾部追加写入(文件原内容保留);若不存在则创 建新文件。 |
t | 文本文件方式打开,若无 t 或 b 则默认为 t |
b | 二进制文件方式打开 |
注:fopen()函数在使用时必须指明权限,但是读写方式可省略(t,b) 读写权限和读写方式可以组合使用,一般权限放在前面,读写方式放在后面。
二.关闭文件
文件使用完毕,必须关闭文件,以避免出现数据错误和丢失。 C 语言中使用 fclose( )函数实现文件关闭操作,当文件成功关闭时函数返回值为 0,若返 回非 0 值,则说明文件关闭发生错误。 Fclose 函数的用法为:
int fclose(File *fp);
fp 为文件指针。
三.以字符形式读写文件
C 语言中读写文件很灵活,每次可以以字符形式读写一个字符,也可以读写一个字符 串,还可以随意字节读写,本节主要介绍以字符形式读写文件。
字符形式读写主要用到两个函数:fgetc( )和 fputc( );
1.Fgetc( )
fgetc 全称为 file get character,即从文件读取一个字符,函数定义形式为:
int fgetc(FILE *fp)
fp 为文件指针。函数返回值为 fgetc 获取到的字符,若读到文件末尾或没有读取成功则 返回 EOF(end of file)。EOF 是 stdio 定义的一个宏值,值为-1。fgetc 函数的返回值类型定义 为 int 而不是 char 就是要容纳这个 EOF。
char ch;
FILE *fp=fopen("a.txt","r+");
ch=fgetc(fp);
上述代码表示从 a.txt 文件读取一个字符,并赋值给变量 ch。 在文件内部有一个专门记录文件读写位置的指针,在 fopen 打开文件时,该指针指向第 一个字节。使用 fgetc 函数读取文件后,该指针向后移动一个字节,这样再次调用 fgetc 函数 就可以继续读取下一个字符了。
EOF 有可能是其他负数,不一定是-1,要看编译器的实现。
2.Fputc( )
fputc 全称为 file put character,即从文件写入一个字符,函数定义形式为:
int fputc(int ch,FILE *fp)
ch 为要写入的字符,fp 为文件指针。函数返回值为 fputc 写入的字符,写入失败返回 EOF(end of file)EOF 是 stdio 定义的一个宏值为-1。之所以 fgetc 函数的返回值类型定义为 int 而不是 char 就是因为要容纳这个 EOF。
char ch='a';
fputc(ch,fp);
上述代码表示把字符 ch 写入到文件 fp。
四.以字符串形式读写文件
fgetc( )和 fputc( )函数每次向文件写入一个字符,但是实际开发往往要一次写入一个字符 串,因此需要用到字符串读写文件函数。
1.fgets( )
fgets( )全称为 file get string,即在指定文件读取字符串,它的函数定义为:
char *fgets (char *str,int n,FILE *fp);
其中,str 为字符数组;n 为整数,代表要读取的字符个数;fp 为文件指针。该函数返回 值为字符数组首地址 str,读取失败和读到文件末尾都会返回 NULL。
2.fputs( )
fputs( )全称为 file put string,即向指定文件写入一个字符串,一般形式为:
int fputs(char *str, File *fp);
str 为要写入的字符串,pf 为文件指针。如写入成功则返回值为非负数,如失败则返回 EOF。
五.以数据块形式读写文件
在 C 语言中,读写文件不一定是以字符的形式,如要读写一个数组或一个结构体变量的 值时之前学习的读写方式就不适用了,需要用 fread( )和 fwrite( )函数来实现上述读写。对于 windows 操作系统,使用 fread( )和 fwrite( )函数要以二进制形式打开文件。
fread( )函数的一般形式为:
fread(buffer,size,count,fp);
fwrite( )函数的一般形式为:
fwrite(buffer,size,count,fp);
其中,buffer 为内存区块的指针,可以是数组、变量、结构体等。fread( )中的 buffer 用 于存放读取到的数据,fwrite( )中的 buffer 用于存放要写入的数据。 size 表示每个数据块的字节数;count 表示要读写的数据块的块数;fp 表示文件指针。 理论上每次读写 size*count 个字节的数据。
fread(fa,4,5,fp);
上述代码表示从 fp 指向的文件中,读取 4 个字节送入一个 fa 中,连续读 5 次,即读取 20 个字节。
六.格式化读写文件
文件读写要用到 fscanf()和 fprintf()函数。 函数一般形式为:
fscanf(FILE *fp,char *format,…);
fprintf(FILE *fp,char *format,…);
其中,fp 为文件指针,format 为格式控制字符串,…表示参数列表。与 scanf()和 printf() 相比,就多了一个文件指针参数 fp。fprintf()返回成功写入字符的个数,失败返回负数。 fscanf()返回参数列表成功赋值的参数个数。
七.随机读写文件
实现随机读写的关键是按需求移动文件指针,这个操作称为文件定位 可以利用 rewind()和 fseek()函数移动文件指针。 rewind()用来将位置指针移动到文件开头,一般形式为
rewind(FILE *fp); 此函数没有返回值。
fseek()用来移动文件指针到任意位置,一般形式为:
fseek(FILE *fp ,long offse,int origin);
例如:要把文件指针移动到距离文件开头 200 个字节的地方:
fseek(fp,200,SEEK_SET);
在文件指针移动好之后就可以进行文件读写了,由于使用二进制方式打开文件,所以常 用 fread()和 fwrite()函数来读写文件。
八.题目分享
1.复制文件内容
编写一个C程序,将一个文件的内容复制到另一个文件中。
#include <stdio.h>
#include <stdlib.h>int main() {FILE *fps, *fpt;char ch;// 打开源文件和目标文件fps = fopen("source.txt", "r");if (fps == NULL) {perror("无法打开源文件");exit(EXIT_FAILURE);}fpt = fopen("target.txt", "w");if (fpt == NULL) {perror("无法打开目标文件");fclose(fps); // 关闭已打开的源文件exit(EXIT_FAILURE);}// 读取源文件内容并写入目标文件while ((ch = fgetc(fps)) != EOF) {fputc(ch, fpt);}// 关闭文件fclose(fps);fclose(fpt);printf("文件复制成功!\n");return 0;
}
2.统计文件中的字符数
编写一个C程序,统计一个文本文件中的字符数。
#include <stdio.h>
#include <stdlib.h>int main() {FILE *fp;int count = 0;char ch;// 打开文件fp = fopen("example.txt", "r");if (fp == NULL) {perror("无法打开文件");exit(EXIT_FAILURE);}// 读取字符并计数while ((ch = fgetc(fp)) != EOF) {count++;}// 关闭文件fclose(fp);printf("文件中的字符总数为:%d\n", count);return 0;
}
3.列出目录中的所有文件
编写一个C程序,列出指定目录中的所有文件。(仅适用于类Unix系统,包括Linux和macOS。在Windows系统上,你需要使用Windows API函数来列出目录中的文件。)
#include <stdio.h>
#include <dirent.h>int main() {DIR *d;struct dirent *dir;d = opendir(".");if (d) {while ((dir = readdir(d)) != NULL) {printf("%s\n", dir->d_name);}closedir(d);}return 0;
}
4.读取并显示文件内容
编写一个C程序,读取一个文本文件的内容,并在控制台上显示。
#include <stdio.h>
#include <stdlib.h>int main() {FILE *fp;char ch;// 打开文件fp = fopen("content.txt", "r");if (fp == NULL) {perror("无法打开文件");exit(EXIT_FAILURE);}// 读取并显示文件内容while ((ch = fgetc(fp)) != EOF) {putchar(ch);}// 关闭文件fclose(fp);return 0;
}
5.向文件中追加内容
编写一个C程序,向一个文本文件的末尾追加一行文本。
#include <stdio.h>
#include <stdlib.h>int main() {FILE *fp;// 打开文件用于追加内容fp = fopen("content.txt", "a");if (fp == NULL) {perror("无法打开文件");exit(EXIT_FAILURE);}// 向文件追加一行文本fprintf(fp, "\n这是追加的文本行。\n");// 关闭文件fclose(fp);printf("文本已成功追加到文件。\n");return 0;
}
6.创建新文件并写入数据
编写一个C程序,创建一个新的文本文件,并向其中写入一些初始数据。
#include <stdio.h>
#include <stdlib.h>int main() {FILE *fp;// 创建并打开新文件用于写入fp = fopen("newfile.txt", "w");if (fp == NULL) {perror("无法创建文件");exit(EXIT_FAILURE);}// 向文件写入数据fprintf(fp, "这是新文件的第一行。\n");fprintf(fp, "这是第二行。\n");// 关闭文件fclose(fp);printf("新文件已创建并写入数据。\n");return 0;
}
7.按行读取文件内容
编写一个C程序,按行读取一个文本文件的内容,并显示每一行的内容。
#include <stdio.h>
#include <stdlib.h>#define MAX_LINE_LENGTH 1024int main() {FILE *fp;char line[MAX_LINE_LENGTH];// 打开文件fp = fopen("lines.txt", "r");if (fp == NULL) {perror("无法打开文件");exit(EXIT_FAILURE);}// 逐行读取文件内容while (fgets(line, MAX_LINE_LENGTH, fp) != NULL) {printf("%s", line);}// 关闭文件fclose(fp);return 0;
}
8.删除文件中的特定行
编写一个C程序,读取一个文本文件,删除文件中的特定行(例如,包含特定单词的行),并将结果保存到新文件中。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>#define MAX_LINE_LENGTH 1024
#define TARGET_WORD "delete"int main() {FILE *fps, *fpt;char line[MAX_LINE_LENGTH];// 打开源文件fps = fopen("source.txt", "r");if (fps == NULL) {perror("无法打开源文件");exit(EXIT_FAILURE);}// 打开目标文件用于写入fpt = fopen("target.txt", "w");if (fpt == NULL) {perror("无法打开目标文件");fclose(fps);exit(EXIT_FAILURE);}// 读取并处理每一行while (fgets(line, MAX_LINE_LENGTH, fps) != NULL) {if (strstr(line, TARGET_WORD) == NULL) {fputs(line, fpt); // 如果行不包含目标单词,则写入新文件}}// 关闭文件fclose(fps);fclose(fpt);printf("特定行已从文件中删除。\n");return 0;
}
9.文件重命名
编写一个C程序,实现文件的重命名功能。
#include <stdio.h>
#include <stdlib.h>int main() {if (rename("oldname.txt", "newname.txt") == 0) {printf("文件重命名成功。\n");} else {perror("文件重命名失败");exit(EXIT_FAILURE);}return 0;
}
10.文件大小
编写一个C程序,计算并显示一个文件的大小(以字节为单位)。
#include <stdio.h>
#include <stdlib.h>int main() {FILE *fp;long size;// 打开文件fp = fopen("file.txt", "rb");if (fp == NULL) {perror("无法打开文件");exit(EXIT_FAILURE);}// 移动到文件末尾fseek(fp, 0, SEEK_END);// 获取文件大小size = ftell(fp);// 关闭文件fclose(fp);printf("文件大小为:%ld 字节\n", size);return 0;
}
11.查找文件
编写一个C程序,在当前目录中查找具有特定扩展名的所有文件。
#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>
#include <string.h>#define EXTENSION ".txt"int main() {DIR *d;struct dirent *dir;char *ext;d = opendir(".");if (d) {while ((dir = readdir(d)) != NULL) {ext = strrchr(dir->d_name, '.'); // 获取文件扩展名if (ext && strcmp(ext, EXTENSION) == 0) {printf("%s\n", dir->d_name);}}closedir(d);}return 0;
}
————由于博主还是大三的在读生,时间有限,每天会不定时更新一些学习经验和一些32的项目,如果喜欢就点点关注吧,大佬们!!!!————
相关文章:

新手c语言讲解及题目分享(十六)--文件系统专项练习
在我刚开始学习c语言的时候就跳过了这一章节,但在后面慢慢发现这一章节还是比较重要的,如果你报考了计算机二级c语言的话,你应该可以看到后面的三个大题有时会涉及到这章。所以说这章还是非常重要的。 目录 前言 一.打开文件 1.Fopen( )函数返回值 2&…...

RabbitMQ本地Ubuntu系统环境部署与无公网IP远程连接服务端实战演示
文章目录 前言1.安装erlang 语言2.安装rabbitMQ3. 安装内网穿透工具3.1 安装cpolar内网穿透3.2 创建HTTP隧道 4. 公网远程连接5.固定公网TCP地址5.1 保留一个固定的公网TCP端口地址5.2 配置固定公网TCP端口地址 💡 推荐 前些天发现了一个巨牛的人工智能学习网站&am…...

[C++#28][多态] 两个条件 | 虚函数表 | 抽象类 | override 和 final | 重载 重写 重定义
目录 0.引入 1.虚函数 1. 虚函数的重写/覆盖 2. 特例1:不加 virtual 关键字的重写 3. 特例2:协变(了解) 2.多态的构成和细节 1. C11 的 override 和 final 1. final 不可重写 2. override 报错检查 ⭕2. 重载、覆盖&…...
List 集合指定值升序降序排列Comparator实现
升序排序 升序排序通常是指从小到大的排序。对于数值类型来说,可以直接使用 compareTo 方法,而对于其他类型,可以根据实际需求实现比较逻辑。 示例代码 import java.util.Comparator; import java.util.List; import java.util.ArrayList;cl…...

【Day07】
目录 MySQL-DQL- 基本查询 MySQL-DQL- 条件查询 MySQL-DQL- 聚合函数 MySQL-DQL- 分组查询 MySQL-DQL- 排序查询 MySQL-DQL- 分页查询 MySQL-DQL- 案例 MySQL-多表设计-一对多 MySQL-多表设计-一对多-外键约束 MySQL-多表设计-一对一&多对多 MySQL-多表设计-案例…...

shell 控制台显示彩色文字的方法
在shell脚本中,如果我们希望在控制台能显示带颜色的文字, 那就需要使用shell中的色彩专用变量代码来进行. shell中的各种颜色代码定义 # 颜色定义 BLACK"\033[0;30m" DARK_GRAY"\033[1;30m" BLUE"\033[0;34m" LIGHT_BLUE"\033[1;3…...

Nginx: 缓存, 不缓存特定内容和缓存失效降低上游压力策略及其配置示例
概述 在负载均衡的过程中,有一个比较重要的概念,就是缓存利用缓存可以很好协调Nginx在客户端和上游服务器之间的速度不匹配的矛盾从而很好的解决整体系统的响应速度 如果用户需要通过Nginx获取某一些内容的时候,发起一个request请求这个请求…...
Python 全栈系列266 Kafka服务的Docker搭建
说明 在大量数据处理任务下的缓存与分发 这个算是来自顾同学的助攻1,我有点java绝缘体的体质,碰到和java相关的安装部署总会碰到点奇怪的问题,不过现在已经搞定了。测试也接近了kafka官方标称的性能。考虑到网络、消息的大小等因素࿰…...

集合框架,List常用API,栈和队列初识
回顾 集合框架 两个重点——ArrayList和HashSet. Vector/ArraysList/LinkedList区别 VectorArraysListLinkedList底层实现数组数组链表线程安全安全不安全不安全增删效率较低较低高扩容*2*1.5-------- (>>)运算级最低,记得加括号。 常…...

构建全景式智慧文旅生态:EasyCVR视频汇聚平台与AR/VR技术的深度融合实践
在科技日新月异的今天,AR(增强现实)和VR(虚拟现实)技术正以前所未有的速度改变着我们的生活方式和工作模式。而EasyCVR视频汇聚平台,作为一款基于云-边-端一体化架构的视频融合AI智能分析平台,可…...
C++结构体声明时初始化
提示:文章 文章目录 前言一、背景二、 2.1 2.2 总结 前言 前期疑问: 本文目标: 一、背景 最近 二、 2.1 c 结构体默认初始化 在C中,结构体的默认成员初始化可以通过构造函数来完成。如果没有为结构体提供构造函数&#x…...

基于微信的热门景点推荐小程序的设计与实现(论文+源码)_kaic
摘 要 近些年来互联网迅速发展人们生活水平也稳步提升,人们也越来越热衷于旅游来提高生活品质。互联网的应用与发展也使得人们获取旅游信息的方法也更加丰富,以前的景点推荐系统现在已经不足以满足用户的要求了,也不能满足不同用户自身的个…...
9、设计模式
设计模式 1、工厂模式 在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。工厂模式作为一种创建模式,一般在创建复杂对象时,考虑使用;在创建简单对象时&…...

数学专题.
数论 1.判断质数 定义:在大于1的整数中,如果只包含1和本身这两个约数,就称为质数or素数 Acwing 866.试除法判断质数 2.预处理质数(筛质数) Acwing 868.筛质数 3.质因数分解 Acwing 867.分解质因数 4.阶乘分解 5.因…...

如何提升网站的收录率?
要提升网站的收录率,其中一个特别有效的工具就是GPC爬虫池,这个工具通过深度研究谷歌SEO算法,吸引谷歌爬虫。 GPC爬虫池的基本原理是构建一个庞大的站群系统,并创建复杂的内链和外链结构,以吸引并留住谷歌蜘蛛 使用GP…...
HALCON根据需要创建自定义函数
在HALCON中,根据需要创建自定义函数是扩展其图像处理和分析功能的有效方式。HALCON支持通过其高级编程接口(HDevelop和C/C、C#、Python等)来创建自定义函数。这里将主要讨论在HDevelop环境中如何创建自定义函数,因为HDevelop是HAL…...
力扣SQL仅数据库(196~569)
196. 删除重复的电子邮箱 题目:编写解决方案 删除 所有重复的电子邮件,只保留一个具有最小 id 的唯一电子邮件。 (对于 SQL 用户,请注意你应该编写一个 DELETE 语句而不是 SELECT 语句。) (对于 Pandas …...

网络基础:理解IP地址、默认网关与网段(IP地址是什么,默认网关是什么,网段是什么,IP地址、默认网关与网段)
前言 在计算机网络中,IP地址、默认网关和网段(也称为子网)之间有着密切的关系。它们是网络通信中的至关重要的概念,但它们并不相同。这里来介绍一下它们之间的关系,简单记录一下 一. IP地址 1. 介绍 IP 地址…...

windows安装php7.4
windows安装php7.4 1.通过官网下载所需的php版本 首先从PHP官网(https://www.php.net/downloads.php)或者Windows下的PHP官网(http://windows.php.net/download/)下载Windows版本的PHP安装包。下载后解压到一个路径下。 2.配…...
【代码随想录|图论part03之后】
代码随想录|数组 704. 二分查找,27. 移除元素 一、part031、101. 孤岛的总面积1.1 dfs版本1.2 BFS版本2.102. 沉没孤岛3、103. 水流问题4、104.建造最大岛屿二、part041、110. 字符串接龙2、105.有向图的完全可达性3、106. 岛屿的周长三、part05-06 并查集理论1、107. 寻找存在…...
[特殊字符] 智能合约中的数据是如何在区块链中保持一致的?
🧠 智能合约中的数据是如何在区块链中保持一致的? 为什么所有区块链节点都能得出相同结果?合约调用这么复杂,状态真能保持一致吗?本篇带你从底层视角理解“状态一致性”的真相。 一、智能合约的数据存储在哪里…...

MPNet:旋转机械轻量化故障诊断模型详解python代码复现
目录 一、问题背景与挑战 二、MPNet核心架构 2.1 多分支特征融合模块(MBFM) 2.2 残差注意力金字塔模块(RAPM) 2.2.1 空间金字塔注意力(SPA) 2.2.2 金字塔残差块(PRBlock) 2.3 分类器设计 三、关键技术突破 3.1 多尺度特征融合 3.2 轻量化设计策略 3.3 抗噪声…...
Matlab | matlab常用命令总结
常用命令 一、 基础操作与环境二、 矩阵与数组操作(核心)三、 绘图与可视化四、 编程与控制流五、 符号计算 (Symbolic Math Toolbox)六、 文件与数据 I/O七、 常用函数类别重要提示这是一份 MATLAB 常用命令和功能的总结,涵盖了基础操作、矩阵运算、绘图、编程和文件处理等…...

R语言速释制剂QBD解决方案之三
本文是《Quality by Design for ANDAs: An Example for Immediate-Release Dosage Forms》第一个处方的R语言解决方案。 第一个处方研究评估原料药粒径分布、MCC/Lactose比例、崩解剂用量对制剂CQAs的影响。 第二处方研究用于理解颗粒外加硬脂酸镁和滑石粉对片剂质量和可生产…...

【C++特殊工具与技术】优化内存分配(一):C++中的内存分配
目录 一、C 内存的基本概念 1.1 内存的物理与逻辑结构 1.2 C 程序的内存区域划分 二、栈内存分配 2.1 栈内存的特点 2.2 栈内存分配示例 三、堆内存分配 3.1 new和delete操作符 4.2 内存泄漏与悬空指针问题 4.3 new和delete的重载 四、智能指针…...
解决:Android studio 编译后报错\app\src\main\cpp\CMakeLists.txt‘ to exist
现象: android studio报错: [CXX1409] D:\GitLab\xxxxx\app.cxx\Debug\3f3w4y1i\arm64-v8a\android_gradle_build.json : expected buildFiles file ‘D:\GitLab\xxxxx\app\src\main\cpp\CMakeLists.txt’ to exist 解决: 不要动CMakeLists.…...
PostgreSQL——环境搭建
一、Linux # 安装 PostgreSQL 15 仓库 sudo dnf install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-$(rpm -E %{rhel})-x86_64/pgdg-redhat-repo-latest.noarch.rpm# 安装之前先确认是否已经存在PostgreSQL rpm -qa | grep postgres# 如果存在࿰…...
在树莓派上添加音频输入设备的几种方法
在树莓派上添加音频输入设备可以通过以下步骤完成,具体方法取决于设备类型(如USB麦克风、3.5mm接口麦克风或HDMI音频输入)。以下是详细指南: 1. 连接音频输入设备 USB麦克风/声卡:直接插入树莓派的USB接口。3.5mm麦克…...
redis和redission的区别
Redis 和 Redisson 是两个密切相关但又本质不同的技术,它们扮演着完全不同的角色: Redis: 内存数据库/数据结构存储 本质: 它是一个开源的、高性能的、基于内存的 键值存储数据库。它也可以将数据持久化到磁盘。 核心功能: 提供丰…...
绕过 Xcode?使用 Appuploader和主流工具实现 iOS 上架自动化
iOS 应用的发布流程一直是开发链路中最“苹果味”的环节:强依赖 Xcode、必须使用 macOS、各种证书和描述文件配置……对很多跨平台开发者来说,这一套流程并不友好。 特别是当你的项目主要在 Windows 或 Linux 下开发(例如 Flutter、React Na…...