C++-linux 7.文件IO(三)文件元数据与 C 标准库文件操作

文件 IO 进阶:文件元数据与 C 标准库文件操作

在 Linux 系统中,文件操作不仅涉及数据的读写,还包括对文件元数据的管理和高层库函数的使用。本文将从文件系统的底层存储机制(inode 与 dentry)讲起,详细解析文件元数据获取函数 stat,并全面介绍 C 标准库中常用的文件操作函数(fopenfclose 及各类读写函数),帮助你掌握用户态文件操作的核心逻辑与最佳实践。

一、文件存储基础:inode 与 dentry

要理解文件操作的本质,需先掌握 Linux 文件系统中两个核心概念——inode 和 dentry,它们是文件识别、路径解析和元数据存储的基础。

1.1 inode:文件的“数字身份证”

inode(索引节点)是文件系统中存储文件元数据的基本单位,本质是一个内核结构体,记录了除文件名外的所有文件关键信息。

核心特性:
  • 唯一性:每个文件(包括普通文件、目录、设备文件、管道等)在同一文件系统中对应唯一的 inode 编号(st_ino),即使文件名修改,inode 编号不变。
  • 持久化存储:inode 存储在磁盘上,包含文件的核心属性,是文件的“身份证”,而文件名仅是指向 inode 的“别名”。
  • 元数据内容:包括文件类型、权限(st_mode)、所有者(st_uid/st_gid)、文件大小(st_size)、时间戳(访问/修改/状态变更时间)、磁盘块位置等关键信息。
为何需要 inode?
  • 实现“硬链接”:多个文件名可指向同一 inode(通过 ln 命令创建),共享数据和权限,删除一个文件名不影响 inode 及其他链接。
  • 高效文件访问:内核通过 inode 直接定位磁盘数据,无需遍历文件名,大幅提升文件操作效率。

1.2 dentry:路径解析的“导航地图”

dentry(目录项)是 Linux 内核在内存中维护的临时缓存结构,用于加速文件路径的解析过程。

核心特性:
  • 内存级缓存:dentry 不持久化存储在磁盘,仅存在于内存的 dentry 缓存(dcache)中,随系统运行动态创建和销毁。
  • 映射关系:记录“文件名 → inode 编号”的映射,以及路径的层级关系(例如解析 /home/user/test.txt 时,需逐级匹配目录的 dentry)。
  • 核心作用:减少磁盘访问次数,加速路径解析。例如首次访问某路径后,dentry 会缓存映射关系,后续访问无需重复查询磁盘 inode。
inode 与 dentry 的关系:
  • inode 是文件的“身份证”(持久化元数据),dentry 是“导航图”(内存级路径映射)。
  • 路径解析流程:内核通过 dentry 缓存逐级查找文件名对应的 inode,若缓存未命中,则从磁盘读取目录 inode 并更新缓存,最终定位到目标文件。

二、stat 函数:获取文件元数据的标准接口

stat 函数是用户态程序获取文件元数据(存储在 inode 中)的核心接口,无需直接操作 inode,即可获取文件类型、权限、大小等关键信息。

2.1 函数原型与功能

#include <sys/stat.h>// 通过路径名获取文件元数据
int stat(const char *pathname, struct stat *buf);
// 通过文件描述符获取文件元数据(更高效,避免路径解析)
int fstat(int fd, struct stat *buf);
// 获取符号链接本身的元数据(不跟随链接指向的文件)
int lstat(const char *pathname, struct stat *buf);
功能:

读取文件的元数据(如 inode 信息、权限、时间戳等),并存储到 struct stat 结构体中。

2.2 参数与返回值

  • pathname:目标文件的路径名(绝对或相对路径,如 "/etc/passwd")。
  • fd:已打开的文件描述符(fstat 专用)。
  • buf:传出参数,指向预分配的 struct stat 结构体,用于存储获取的元数据。
  • 返回值:成功返回 0;失败返回 -1,并设置 errno(如 ENOENT 表示文件不存在,EACCES 表示权限不足)。

2.3 关键数据结构:struct stat

struct stat 结构体包含文件的所有元数据,核心字段如下:

字段类型含义说明
st_inoino_t文件的 inode 编号(唯一标识)。
st_modemode_t文件类型(如普通文件、目录)和权限位(如 0755 表示 rwxr-xr-x)。
st_uiduid_t文件所有者的用户 ID(UID)。
st_gidgid_t文件所有者的组 ID(GID)。
st_sizeoff_t文件大小(字节数,仅对普通文件有效)。
st_blksizeblksize_t文件系统的最佳 I/O 块大小(按此大小读写可提高效率)。
st_blocksblkcnt_t文件占用的磁盘块数(每块通常为 512 字节)。
st_atimetime_t最后访问时间(如 read 操作触发更新)。
st_mtimetime_t最后修改时间(如 write 操作修改内容时触发更新)。
st_ctimetime_t最后状态变更时间(如权限、所有者修改时触发更新,区别于内容修改)。
st_nlinknlink_t硬链接数量(ln 命令创建的链接数,文件删除需此值减为 0)。

2.4 核心用法:通过 st_mode 判断文件类型

st_mode 的高 4 位标识文件类型,可通过以下宏快速判断:

含义适用场景
S_ISREG(m)是否为普通文件判断常规数据文件
S_ISDIR(m)是否为目录判断文件夹
S_ISCHR(m)是否为字符设备文件判断终端、串口等字符设备
S_ISBLK(m)是否为块设备文件判断硬盘、U盘等块设备
S_ISLNK(m)是否为符号链接lstat 可检测
S_ISFIFO(m)是否为管道文件判断匿名/命名管道
S_ISSOCK(m)是否为套接字文件判断网络套接字

(注:mstruct stat 中的 st_mode 字段)

2.5 编程示例:使用 stat 获取文件信息

#include <stdio.h>
#include <sys/stat.h>
#include <time.h>  // 用于 ctime 转换时间戳int main() {const char *file_path = "/etc/passwd";struct stat file_info;// 获取文件元数据if (stat(file_path, &file_info) == -1) {perror("stat failed");  // 输出错误原因(如文件不存在)return 1;}// 打印基础信息printf("文件路径:%s\n", file_path);printf("inode 编号:%ld\n", (long)file_info.st_ino);printf("文件大小:%ld 字节\n", (long)file_info.st_size);printf("硬链接数量:%ld\n", (long)file_info.st_nlink);printf("所有者 UID:%ld,组 GID:%ld\n", (long)file_info.st_uid, (long)file_info.st_gid);// 解析权限(通过 &0777 提取后 9 位权限位)printf("文件权限:%o(八进制)\n", file_info.st_mode & 0777);// 解析时间戳(转换为本地时间字符串)printf("最后访问时间:%s", ctime(&file_info.st_atime));printf("最后修改时间:%s", ctime(&file_info.st_mtime));printf("最后状态变更时间:%s", ctime(&file_info.st_ctime));// 判断文件类型if (S_ISREG(file_info.st_mode)) {printf("文件类型:普通文件\n");} else if (S_ISDIR(file_info.st_mode)) {printf("文件类型:目录\n");} else if (S_ISCHR(file_info.st_mode)) {printf("文件类型:字符设备\n");}return 0;
}
输出说明:

运行后将打印 /etc/passwd 的 inode 编号、大小、权限等信息,若文件不存在则输出 stat failed: No such file or directory

三、C 标准库文件操作函数详解

C 标准库提供了一套封装底层系统调用的文件操作函数,基于“文件流(FILE*)”实现,自带缓冲区,简化了文件读写流程,是用户态文件操作的常用工具。

3.1 fopen:打开文件流

fopen 用于创建或打开文件,返回文件流指针(FILE*),是所有 C 库文件操作的起点。

函数原型:
#include <stdio.h>FILE *fopen(const char *filename, const char *mode);
参数说明:
  • filename:文件路径(绝对或相对路径,如 "./test.txt""/tmp/log.txt")。
  • mode:打开模式,决定文件的读写权限和行为,常用模式如下:
模式含义说明适用场景
"r"只读模式,文件必须存在,否则打开失败。读取已存在的文件
"w"只写模式,文件不存在则创建,存在则清空原有内容。覆盖写入新内容
"a"追加模式,文件不存在则创建,写入内容自动追加到文件末尾(不覆盖原有内容)。日志记录、持续追加数据
"r+"读写模式,文件必须存在,可读写但不清空内容。修改已存在的文件
"w+"读写模式,文件不存在则创建,存在则清空内容。新建或覆盖文件并读写
"a+"读写模式,文件不存在则创建,写入追加到末尾,读取从开头开始。追加数据同时需要读取历史内容

扩展模式:

  • 二进制模式:模式后加 b(如 "rb""wb+"),表示按字节读写(不转换换行符),适用于图片、视频等二进制文件。
  • 文本模式:默认模式(不加 b),Windows 下会自动转换 \n\r\n(Linux 无区别)。
返回值:
  • 成功:返回非 NULLFILE* 指针(后续操作基于此指针)。
  • 失败:返回 NULL(需检查!否则操作空指针会导致程序崩溃)。
示例:打开文件用于写入
FILE *fp = fopen("test.txt", "w");  // 以只写模式打开,不存在则创建
if (fp == NULL) {  // 必须检查返回值perror("fopen failed");  // 输出错误信息(如权限不足、路径不存在)return 1;
}
// 文件操作...
fclose(fp);  // 操作完成后关闭

3.2 fclose:关闭文件流

fclose 用于关闭已打开的文件流,释放资源并确保缓冲区数据写入磁盘。

函数原型:
#include <stdio.h>int fclose(FILE *stream);
参数与返回值:
  • streamfopen 返回的文件流指针(FILE*)。
  • 返回值:成功返回 0;失败返回 EOF(通常因磁盘错误或流已关闭)。
核心作用:
  1. 刷新用户态缓冲区:将未写入磁盘的数据通过底层系统调用刷盘(避免数据丢失)。
  2. 释放资源:关闭底层文件描述符,释放文件流占用的内存。
注意事项:
  • 必须调用:未关闭的文件流可能导致缓冲区数据丢失或文件描述符泄漏(系统允许打开的文件数有限)。
  • 检查返回值:虽不常见,但 fclose 失败可能意味着数据未完全写入(如磁盘满),需处理错误。
示例:关闭文件流
FILE *fp = fopen("test.txt", "w");
if (fp == NULL) { perror("fopen failed"); return 1; }// 写入数据...// 关闭文件流并检查错误
if (fclose(fp) == EOF) {perror("fclose failed");  // 数据可能未完全写入return 1;
}

3.3 写入函数:fputc、fputs、fprintf

C 标准库提供多种写入函数,分别适用于单个字符、字符串和格式化数据的场景。

3.3.1 fputc:写入单个字符
#include <stdio.h>// 向文件流写入单个字符
int fputc(int character, FILE *stream);
  • 参数character 为待写入字符(int 类型兼容 EOF);stream 为目标文件流。
  • 返回值:成功返回写入的字符(转换为 int);失败返回 EOF
示例:
FILE *fp = fopen("test.txt", "w");
if (fp == NULL) { perror("fopen failed"); return 1; }fputc('H', fp);  // 写入 'H'
fputc('i', fp);  // 写入 'i'
fputc('\n', fp); // 写入换行符fclose(fp);  // 文件内容:Hi\n
3.3.2 fputs:写入字符串
#include <stdio.h>// 向文件流写入字符串(不自动添加换行符)
int fputs(const char *str, FILE *stream);
  • 参数str 为以 \0 结尾的字符串(\0 不写入);stream 为目标文件流。
  • 返回值:成功返回非负值;失败返回 EOF
优势:

puts 更灵活(可指定输出流),且不自动添加换行符,控制更精确。

示例:
FILE *fp = fopen("test.txt", "w");
if (fp == NULL) { perror("fopen failed"); return 1; }fputs("Hello, ", fp);   // 写入 "Hello, "
fputs("World!\n", fp);  // 写入 "World!\n"fclose(fp);  // 文件内容:Hello, World!
3.3.3 fprintf:格式化写入
#include <stdio.h>// 按格式字符串向文件流写入数据(类似 printf,但输出到文件)
int fprintf(FILE *stream, const char *format, ...);
  • 参数stream 为目标文件流;format 为格式字符串(如 "%s %d %.2f");... 为可变参数(待写入的数据)。
  • 返回值:成功返回写入的字符数;失败返回负值。
示例:写入格式化数据
#include <stdio.h>int main() {FILE *fp = fopen("user_info.txt", "w");if (fp == NULL) { perror("fopen failed"); return 1; }char name[] = "张三";int age = 20;float score = 95.5;// 格式化写入数据fprintf(fp, "姓名:%s,年龄:%d,分数:%.2f\n", name, age, score);fclose(fp);// 文件内容:姓名:张三,年龄:20,分数:95.50return 0;
}
说明:

fprintf 支持与 printf 相同的格式占位符(%s%d%f 等),可将多种类型的数据按指定格式写入文件,是格式化输出的常用工具。

3.4 读取函数:fgetc、fgets、fscanf

C 标准库提供多种读取函数,分别适用于单个字符、行读取和格式化数据的场景,需注意区分文件末尾与读取错误。

3.4.1 fgetc:读取单个字符
#include <stdio.h>// 从文件流读取单个字符
int fgetc(FILE *stream);
  • 参数stream 为目标文件流指针。
  • 返回值
    • 成功:返回读取的字符(转换为 int 类型,范围 0~255)。
    • 结束/失败:返回 EOF(需通过 feof(stream) 判断是否为文件末尾,ferror(stream) 判断是否为错误)。
关键:区分“文件末尾”与“错误”
  • feof(stream):若流已到达文件末尾,返回非 0 值(真)。
  • ferror(stream):若流发生读取错误,返回非 0 值(真)。
示例:循环读取文件内容
#include <stdio.h>int main() {FILE *fp = fopen("test.txt", "r");if (fp == NULL) {perror("fopen failed");return 1;}int ch;  // 用 int 存储,避免与 EOF 混淆(EOF 为 -1)while ((ch = fgetc(fp)) != EOF) {putchar(ch);  // 将读取的字符输出到屏幕}// 判断结束原因if (feof(fp)) {printf("\n读取完成:已到达文件末尾\n");} else if (ferror(fp)) {perror("读取错误");}fclose(fp);return 0;
}
说明:

若文件内容为 Hello, World!,程序会将内容逐字符输出到屏幕,结束时提示“已到达文件末尾”。

3.4.2 fgets:读取一行字符串(安全版)
#include <stdio.h>// 从文件流读取最多 num-1 个字符到缓冲区(自动添加 '\0')
char *fgets(char *str, int num, FILE *stream);
  • 参数
    • str:存储读取结果的缓冲区(需提前分配内存)。
    • num:最大读取字符数(实际读取 num-1 个,预留 '\0' 作为字符串结束标志)。
    • stream:目标文件流指针。
  • 返回值
    • 成功:返回 str(缓冲区指针)。
    • 结束/失败:返回 NULL(若文件末尾前已读取部分数据,str 仍有效;若错误,str 内容不确定)。
优势:防止缓冲区溢出

fgets 明确限制读取长度,避免了 gets(无长度限制)的安全隐患,是读取字符串的首选函数。

示例:读取文件内容(按行读取)
#include <stdio.h>int main() {FILE *fp = fopen("test.txt", "r");if (fp == NULL) {perror("fopen failed");return 1;}char buf[100];  // 最多存储 99 个字符 + '\0'while (fgets(buf, sizeof(buf), fp) != NULL) {printf("读取内容:%s", buf);  // 包含换行符(若一行未超缓冲区)}fclose(fp);return 0;
}
说明:

若文件内容为多行文本,fgets 会逐行读取,每次最多读取 99 个字符(缓冲区大小 100),换行符会被包含在结果中。

3.4.3 fscanf:格式化读取
#include <stdio.h>// 按格式字符串从文件流读取数据(类似 scanf,但输入来自文件)
int fscanf(FILE *stream, const char *format, ...);
  • 参数
    • stream 为目标文件流;
    • format 为格式字符串(如 "%s %d %f");
    • ... 为存储结果的变量地址(需用 & 取地址,字符串数组除外)。
  • 返回值:成功匹配并赋值的参数个数;文件末尾或失败返回 EOF
示例:读取格式化数据

假设有文件 user.txt,内容为 张三 20 95.5,读取代码如下:

#include <stdio.h>int main() {FILE *fp = fopen("user.txt", "r");if (fp == NULL) {perror("fopen failed");return 1;}char name[20];int age;float score;// 按格式读取数据int ret = fscanf(fp, "%s %d %f", name, &age, &score);if (ret == 3) {  // 成功匹配 3 个参数printf("姓名:%s,年龄:%d,分数:%.2f\n", name, age, score);// 输出:姓名:张三,年龄:20,分数:95.50} else if (ret == EOF) {perror("读取失败");} else {printf("格式不匹配,成功读取 %d 个参数\n", ret);}fclose(fp);return 0;
}
注意事项:
  • 格式字符串需与文件内容严格匹配(如空格、数据类型),否则可能读取失败。
  • 字符串 %s 遇空格/换行停止读取,若需读取含空格的字符串,需用 fgets 配合 sscanf 处理。

3.5 标准流:stdin、stdout、stderr

C 标准库预定义了三个无需 fopen 即可直接使用的文件流,对应系统默认的输入输出设备,是程序与用户交互的基础。

标准流对应设备类型特性常用场景
stdin标准输入(键盘)输入流行缓冲:输入数据需按回车后才提交给程序(可通过 fflush(stdin) 刷新)。读取用户输入
stdout标准输出(屏幕)输出流行缓冲:输出数据遇换行或缓冲区满时才显示(可通过 fflush(stdout) 强制刷新)。输出正常结果
stderr标准错误(屏幕)错误流无缓冲:数据立即显示,不受缓冲区影响。输出错误信息、异常提示
示例:使用标准流
#include <stdio.h>
#include <string.h>int main() {// 1. 从 stdin 读取用户输入char input[100];fprintf(stdout, "请输入姓名:");  // 等价于 printf("请输入姓名:")fflush(stdout);  // 强制刷新缓冲区(确保提示先显示)if (fgets(input, sizeof(input), stdin) == NULL) {fprintf(stderr, "读取输入失败!\n");  // 错误信息输出到 stderrreturn 1;}// 去除输入中的换行符(若存在)input[strcspn(input, "\n")] = '\0';// 2. 向 stdout 输出结果fprintf(stdout, "你好,%s!\n", input);  // 等价于 printf("你好,%s!\n", input)// 3. 模拟错误输出if (strlen(input) == 0) {fprintf(stderr, "错误:姓名不能为空!\n");  // 错误信息实时显示}return 0;
}
说明:
  • printf(...) 本质是 fprintf(stdout, ...) 的宏定义。
  • fputs("消息", stdout) 等价于 puts("消息")(但 puts 会自动添加换行符)。
  • stderr 输出的信息通常在终端中以红色高亮显示,便于区分正常输出与错误。

四、文件 IO 核心流程与最佳实践总结

核心流程

C 标准库文件操作的完整流程可概括为:

打开文件(fopen) → 读写操作(fputc/fgets 等) → 关闭文件(fclose)

关键注意事项

  1. 检查 fopen 返回值:始终判断 FILE* 是否为 NULL,避免操作空指针导致程序崩溃。
  2. 及时调用 fclose:确保缓冲区数据刷盘,释放文件描述符,避免资源泄漏(系统允许打开的文件数有限)。
  3. 优先使用安全函数:用 fgets 替代 gets(防止缓冲区溢出),用 snprintf 替代 sprintf(格式化输出更安全)。
  4. 区分文本与二进制模式:读写文本文件用默认模式,读写图片、视频等二进制文件需加 b 标志(如 "rb""wb"),避免换行符转换导致数据损坏。
  5. 处理读取结束原因:用 feofferror 区分“文件末尾”和“读取错误”,避免误判。
  6. 格式化操作需匹配格式fscanf/fprintf 的格式字符串必须与数据类型严格匹配,否则易出现数据错乱或读取失败。

总结

本文从文件系统底层的 inode 与 dentry 机制出发,详细解析了文件元数据获取函数 stat 的用法,随后全面介绍了 C 标准库中文件操作的核心函数:

  • fopen/fclose 负责文件流的打开与关闭,是所有操作的基础;
  • fputc/fputs/fprintf 实现不同场景的写入需求,支持字符、字符串和格式化数据;
  • fgetc/fgets/fscanf 实现灵活的读取功能,需注意区分文件末尾与错误;
  • 标准流 stdin/stdout/stderr 简化了程序与用户的交互。

掌握这些函数的用法和底层原理,能高效、安全地处理文件 IO 操作,无论是日常应用开发还是系统工具编写,都能打下坚实的基础。

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

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

相关文章

WordPress Ads Pro Plugin本地文件包含漏洞(CVE-2025-4380)

免责声明 本文档所述漏洞详情及复现方法仅限用于合法授权的安全研究和学术教育用途。任何个人或组织不得利用本文内容从事未经许可的渗透测试、网络攻击或其他违法行为。 前言:我们建立了一个更多,更全的知识库。每日追踪最新的安全漏洞,追中25HW情报。 更多详情: http…

从爆红到跑路:AI明星Manus为何仅用四个月就“抛弃”了中国?

目录 前言 一、资本的“无形之手”&#xff1a;7500万美元融资背后的“投名状” 二、技术的双重困境&#xff1a;算力封锁与“应用层”的原罪 三、战略的错判&#xff1a;一场与中国市场的“双向奔赴”失败 四、事件的启示&#xff1a;当“出海”变成“出走” &#x1f3a…

CCF-GESP 等级考试 2025年6月认证Python三级真题解析

1 单选题&#xff08;每题 2 分&#xff0c;共 30 分&#xff09;第1题 2025年4月19日在北京举行了一场颇为瞩目的人形机器人半程马拉松赛。比赛期间&#xff0c;跑动着的机器人会利用 身上安装的多个传感器所反馈的数据来调整姿态、保持平衡等&#xff0c;那么这类传感器类似于…

16.使用ResNet网络进行Fashion-Mnist分类

16.1 ResNet网络结构设计################################################################################################################ #ResNet ################################################################################################################…

C# 结构体 和 类 的区别

✅ 结构体&#xff08;struct&#xff09;是值类型&#xff08;Value Type&#xff09;和类&#xff08;class&#xff09;不同&#xff0c;结构体在赋值和传参时是复制值本身&#xff0c;而不是引用地址。✅ 一、结构体的基本使用示例&#xff1a;using System;struct Point {…

MacBook Air M4 安装 VMware Fusion Pro

VMware Fusion Pro已经对消费者免费了&#xff0c;在Windows系统上的安装和使用教程比较多&#xff0c;Mac上竟然没多少&#xff0c;还充斥着大量的广告以及付费软件&#xff0c;所以趁着今天要安装虚拟机&#xff0c;记录一下完整过程。 1&#xff0c;注册博通账号与登录 首…

vue的优缺点

Vue的优点轻量级框架 Vue的核心库仅关注视图层&#xff0c;体积小巧&#xff08;约20KB&#xff09;&#xff0c;加载速度快&#xff0c;适合快速开发小型到中型项目。易于上手 文档清晰且中文友好&#xff0c;API设计简洁&#xff0c;学习曲线平缓。熟悉HTML、CSS和JavaScript…

闲庭信步使用图像验证平台加速FPGA的开发:第七课——获取RAW图像

&#xff08;本系列只需要modelsim即可完成数字图像的处理&#xff0c;每个工程都搭建了全自动化的仿真环境&#xff0c;只需要双击top_tb.bat文件就可以完成整个的仿真&#xff0c;大大降低了初学者的门槛&#xff01;&#xff01;&#xff01;&#xff01;如需要该系列的工程…

在前端项目中是如何解决跨域的

&#x1f4d8; 前端项目中跨域问题及解决方式详解&#xff08;Vite 项目&#xff09;一、&#x1f310; 什么是跨域&#xff1f;跨域&#xff08;Cross-Origin&#xff09; 指的是在浏览器中&#xff0c;前端页面与服务器之间的协议、域名或端口不一致而引发的安全限制。✅ 浏览…

代码审计-Struts2漏洞分析

一、Struts2介绍 Struts2 是一个基于 MVC&#xff08;Model-View-Controller&#xff09; 设计模式的开源 Java Web 应用框架&#xff0c;由 Apache 软件基金会维护。它是 Struts1 和 WebWork 框架的整合产物&#xff0c;以 WebWork 为核心&#xff0c;通过拦截器机制实现业务逻…

三、神经网络——网络优化方法

三、网络优化方法 1.梯度下降算法梯段下降算法是一种寻找使损失函数最小化的方法&#xff0c;从数学上的角度来看&#xff0c;梯度的方向是函数增长速度最快的方向&#xff0c;那么梯度的反方向就是函数减少最快的方向&#xff0c;所以有WijnewWijold−η∂E∂WijW_{ij}^{new} …

HTML/JOSN复习总结

HTML 基础 什么是 HTML? 1.HTML是一门语言&#xff0c;所有的网页都是用HTML这门语言编写出来的 2.HTML(HyperText Markup Language):超文本标记语言。 >超文本:超越了文本的限制&#xff0c;比普通文本更强大。除了文字信息&#xff0c;还可以定义图片、音频、视频等内…

Golang中的内置类型

A. int B. string C. struct D. array 首先&#xff0c;内置类型是指不需要引入任何关于这些数据类型的包&#xff0c;就可以引用的数据类型。那么&#xff0c;内置类型主要包括基本类型&#xff0c;复合类型&#xff0c;控制并发&#xff0c;高级抽象&#xff0c;特殊类型。…

通过命名空间引用了 Application 类,php不会自动包含路径文件吗?

示例代码&#xff1a;报错提示找不到Application类 use mvc\core\Application;$app new Application(); // 定义路由 $app->get(/, HomeControllerindex); $app->get(/user, UserControllershow); $app->post(/user, UserControllercreate);// 运行应用 $app->run…

PlantUML 基础使用技术文档

目录 摘要 1. 什么是 PlantUML 2. 安装与环境配置 2.1 本地使用 2.2 在线使用 3. 基本语法 3.1 示例&#xff1a;系统架构图 3.2 常用元素 4. 渲染方式 4.1 VSCode 4.2 在线渲染 4.3 生成图片 5. 推荐实践 6. 常见图类型 7. 进阶功能 8. 典型应用场景 摘要 Pl…

Android Notification 通过增加addAction 跳转回Service重新执行逻辑

1.场景描述在App内升级过程中&#xff0c;apk下载过程中网络波动导致连接超时&#xff0c;下载失败后Service生命周期结束。前台通知也被清除。2.解决思路在通知栏中增加重试按钮重启下载服务。3.代码NotificationManager mNotificationManager (NotificationManager) getSy…

带货视频评论的用户洞察 科大讯飞AI算法赛 Datawhale AI夏令营

赛题 2025 iFLYTEK AI开发者大赛https://challenge.xfyun.cn/topic/info?typevideo-comment-insight 一、赛事背景 在电商直播爆发式增长的数字化浪潮下&#xff0c;短视频平台积累了海量带货视频及用户互动数据。这些数据不仅是消费者对商品体验的直接反馈&#xff0c;更蕴…

JAVA生成PDF(itextpdf)

java生成PDF有多种方式&#xff0c;比如itextpdf、 Apache PDFBox、Flying Saucer (XHTMLRenderer)、 OpenPDF等。今天要介绍的是itextpdf&#xff0c;及在开发过程中处理的问题。1. 引入POM<!--PDF导出POM--><dependency><groupId>com.itextpdf</groupId…

[爬虫知识] 深入理解多进程/多线程/协程的异步逻辑

相关爬虫实战案例&#xff1a;[爬虫实战] 多进程/多线程/协程-异步爬取豆瓣Top250 相关爬虫专栏&#xff1a;JS逆向爬虫实战 爬虫知识点合集 爬虫实战案例 逆向知识点合集 前言&#xff1a; 面对海量的目标数据&#xff0c;传统单线程、同步的爬取方式往往效率低下&#x…

Oracle RAC 11.2.0.4 更新SYSASM和SYS密码

前言 从技术角度看&#xff0c;SYSASM是Oracle 10g R2引入的ASM管理员角色&#xff0c;而SYS是数据库实例的超级用户&#xff0c;SYS账户无法管理ASM磁盘组。SYSASM权限是集群级别的&#xff0c;比如在添加磁盘组时&#xff0c;这个操作会影响所有节点&#xff1b;而SYS用户的权…