当前位置: 首页 > news >正文

深入C语言文件操作:从库函数到系统调用

引言

文件操作是编程中不可或缺的一部分,尤其在C语言中,文件操作不仅是处理数据的基本手段,也是连接程序与外部世界的重要桥梁。C语言提供了丰富的库函数来处理文件,如 fopenfclosefreadfwrite 等。然而,这些库函数实际上是基于操作系统提供的系统调用构建的。理解库函数和系统调用之间的关系,不仅有助于编写高效的代码,还能帮助我们更好地理解底层操作系统的机制。

本文将深入探讨C语言文件操作中的库函数和系统调用,解释它们的工作原理、区别和联系,并通过实际示例展示如何使用这些函数。
在这里插入图片描述

C标准库函数与系统调用概述

6.1 C标准库函数

C标准库函数是ANSI C标准中定义的一组函数,它们提供了一种跨平台的方式来处理文件操作。这些函数通常在 stdio.h 头文件中声明,并且在大多数操作系统中都有实现。常见的文件操作库函数包括:

  • fopen:打开文件。
  • fclose:关闭文件。
  • fread:从文件中读取数据。
  • fwrite:向文件中写入数据。
  • fgetc:从文件中读取一个字符。
  • fputc:向文件中写入一个字符。
  • fgets:从文件中读取一行。
  • fputs:向文件中写入一行。
  • fseek:移动文件指针。
  • ftell:获取文件指针的当前位置。
  • rewind:将文件指针重置到文件开头。

6.2 系统调用

系统调用是操作系统提供给用户程序的一组接口,用于请求操作系统执行特定的低级操作。系统调用通常在内核态执行,提供了对硬件设备的直接访问。常见的文件操作系统调用包括:

  • open:打开文件。
  • close:关闭文件。
  • read:从文件中读取数据。
  • write:向文件中写入数据。
  • lseek:移动文件指针。
  • ioctl:控制设备。

库函数与系统调用的区别

6.3 工作空间不同

  • 库函数:运行在用户态,通常包含在标准库中,如 glibc
  • 系统调用:运行在内核态,由操作系统内核提供。

6.4 缓冲机制不同

  • 库函数:通常使用缓冲机制来提高性能。例如,freadfwrite 会先将数据读取到内存缓冲区,然后再批量处理。
  • 系统调用:不使用缓冲机制,每次调用都会直接与文件系统交互。

6.5 可移植性不同

  • 库函数:具有良好的可移植性,可以在不同的操作系统上使用相同的接口。
  • 系统调用:依赖于特定的操作系统,不同操作系统的系统调用接口可能不同。

6.6 性能差异

  • 库函数:由于使用了缓冲机制,减少了用户态和内核态之间的切换次数,通常性能更高。
  • 系统调用:每次调用都会导致用户态和内核态之间的切换,性能较低。

库函数与系统调用的联系

尽管库函数和系统调用在许多方面有所不同,但它们之间存在着密切的联系。实际上,许多库函数最终会调用系统调用来完成实际的文件操作。

6.7 fopenopen

fopen 函数用于打开文件,并返回一个指向 FILE 结构的指针。fopen 实际上调用了 open 系统调用。

示例代码:

#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>int main() {// 使用 fopen 打开文件FILE *file = fopen("example.txt", "r");if (file == NULL) {fprintf(stderr, "打开文件失败: %s\n", strerror(errno));return 1;}// 使用 open 系统调用打开文件int fd = open("example.txt", O_RDONLY);if (fd == -1) {perror("打开文件失败");return 1;}fclose(file);close(fd);return 0;
}

6.8 freadread

fread 函数用于从文件中读取数据,并返回实际读取的数据项数。fread 实际上调用了 read 系统调用。

示例代码:

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>int main() {// 使用 fopen 打开文件FILE *file = fopen("example.txt", "r");if (file == NULL) {fprintf(stderr, "打开文件失败: %s\n", strerror(errno));return 1;}// 使用 open 系统调用打开文件int fd = open("example.txt", O_RDONLY);if (fd == -1) {perror("打开文件失败");return 1;}char buffer[100];size_t bytes_read;// 使用 fread 读取文件bytes_read = fread(buffer, 1, sizeof(buffer), file);if (ferror(file)) {fprintf(stderr, "读取文件失败: %s\n", strerror(errno));fclose(file);close(fd);return 1;}buffer[bytes_read] = '\0';printf("fread: %s\n", buffer);// 使用 read 系统调用读取文件bytes_read = read(fd, buffer, sizeof(buffer));if (bytes_read == -1) {perror("读取文件失败");close(fd);return 1;}buffer[bytes_read] = '\0';printf("read: %s\n", buffer);fclose(file);close(fd);return 0;
}

6.9 fwritewrite

fwrite 函数用于向文件中写入数据,并返回实际写入的数据项数。fwrite 实际上调用了 write 系统调用。

示例代码:

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>int main() {// 使用 fopen 打开文件FILE *file = fopen("example.txt", "w");if (file == NULL) {fprintf(stderr, "打开文件失败: %s\n", strerror(errno));return 1;}// 使用 open 系统调用打开文件int fd = open("example.txt", O_WRONLY | O_CREAT, 0644);if (fd == -1) {perror("打开文件失败");return 1;}char *message = "Hello, World!\n";// 使用 fwrite 写入文件if (fwrite(message, 1, strlen(message), file) != strlen(message)) {if (ferror(file)) {fprintf(stderr, "写入文件失败: %s\n", strerror(errno));fclose(file);close(fd);return 1;}}// 使用 write 系统调用写入文件if (write(fd, message, strlen(message)) == -1) {perror("写入文件失败");close(fd);return 1;}fclose(file);close(fd);return 0;
}

6.10 fcloseclose

fclose 函数用于关闭文件,并刷新缓冲区。fclose 实际上调用了 close 系统调用。

示例代码:

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>int main() {// 使用 fopen 打开文件FILE *file = fopen("example.txt", "w");if (file == NULL) {fprintf(stderr, "打开文件失败: %s\n", strerror(errno));return 1;}// 使用 open 系统调用打开文件int fd = open("example.txt", O_WRONLY | O_CREAT, 0644);if (fd == -1) {perror("打开文件失败");return 1;}char *message = "Hello, World!\n";// 使用 fwrite 写入文件if (fwrite(message, 1, strlen(message), file) != strlen(message)) {if (ferror(file)) {fprintf(stderr, "写入文件失败: %s\n", strerror(errno));fclose(file);close(fd);return 1;}}// 使用 write 系统调用写入文件if (write(fd, message, strlen(message)) == -1) {perror("写入文件失败");close(fd);return 1;}// 使用 fclose 关闭文件if (fclose(file) != 0) {fprintf(stderr, "关闭文件失败: %s\n", strerror(errno));close(fd);return 1;}// 使用 close 系统调用关闭文件if (close(fd) == -1) {perror("关闭文件失败");return 1;}return 0;
}

文件描述符与缓冲区

6.11 文件描述符

文件描述符(File Descriptor,FD)是一个用于引用打开文件和其他类型的I/O资源的整数。每个进程都有自己的文件描述符表,用于跟踪进程打开的所有文件和I/O资源。

  • 唯一标识:文件描述符为每个打开的文件或I/O资源提供了一个唯一的标识符,通常是一个非负整数。
  • 文件描述符表:每个进程都有自己的文件描述符表,这是一个内核数据结构,用于跟踪进程打开的所有文件和I/O资源。
  • 系统调用:文件描述符通常通过系统调用如 openreadwriteclose 等进行操作。open 调用返回一个新的文件描述符,readwrite 使用文件描述符来读取或写入数据,而 close 用于释放文件描述符。
  • 标准流:Linux为标准输入(stdin)、标准输出(stdout)和标准错误(stderr)分别分配了文件描述符0、1和2。
  • 缓冲机制:Linux内核可能会对通过文件描述符进行的I/O操作使用缓冲机制,以提高性能和减少实际的磁盘I/O操作。
  • 错误处理:当系统调用失败时,会返回-1,并且全局变量 errno 被设置为表示错误的特定值。
  • 多路复用:文件描述符可以用于I/O多路复用机制,如 selectpollepoll,允许进程同时监控多个文件描述符上的I/O状态。
  • 继承性:当创建新进程时,子进程会继承父进程的文件描述符表中的文件描述符,除非它们在子进程中被显式地关闭。
  • 重定向:文件描述符可以通过 dupdup2 等函数进行重定向,允许将一个文件描述符的引用复制到另一个文件描述符上。
  • 文件锁:文件描述符可以用于对文件加锁,以控制对文件的并发访问。

6.12 缓冲区机制

缓冲区机制是C标准库中用于提高I/O性能的一种技术。缓冲区可以减少用户态和内核态之间的切换次数,从而提高性能。

  • 全缓冲:对于文件,通常是全缓冲的。这意味着数据会先写入缓冲区,当缓冲区满或文件关闭时,数据才会被写入文件。
  • 行缓冲:对于终端输入输出,通常是行缓冲的。这意味着数据会在遇到换行符时被写入文件。
  • 无缓冲:对于标准错误输出,通常是无缓冲的。这意味着数据会立即被写入文件。

实际应用案例

6.13 文件拷贝示例

下面是一个使用库函数和系统调用实现文件拷贝的示例。该示例展示了如何结合使用库函数和系统调用来完成文件操作。

示例代码:

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>int copy_file(const char *src_path, const char *dst_path) {// 使用 fopen 打开源文件FILE *src_file = fopen(src_path, "rb");if (src_file == NULL) {fprintf(stderr, "打开源文件失败: %s\n", strerror(errno));return 1;}// 使用 open 系统调用打开目标文件int dst_fd = open(dst_path, O_WRONLY | O_CREAT | O_TRUNC, 0644);if (dst_fd == -1) {fprintf(stderr, "打开目标文件失败: %s\n", strerror(errno));fclose(src_file);return 1;}char buffer[1024];size_t bytes_read;while ((bytes_read = fread(buffer, 1, sizeof(buffer), src_file)) > 0) {if (ferror(src_file)) {fprintf(stderr, "读取源文件失败: %s\n", strerror(errno));fclose(src_file);close(dst_fd);return 1;}if (write(dst_fd, buffer, bytes_read) == -1) {perror("写入目标文件失败");fclose(src_file);close(dst_fd);return 1;}}if (ferror(src_file)) {fprintf(stderr, "读取源文件失败: %s\n", strerror(errno));fclose(src_file);close(dst_fd);return 1;}if (fclose(src_file) != 0) {fprintf(stderr, "关闭源文件失败: %s\n", strerror(errno));close(dst_fd);return 1;}if (close(dst_fd) == -1) {perror("关闭目标文件失败");return 1;}return 0;
}int main() {const char *src_path = "source.txt";const char *dst_path = "destination.txt";if (copy_file(src_path, dst_path) == 0) {printf("文件复制成功\n");} else {printf("文件复制失败\n");}return 0;
}

文件操作的底层原理

6.14 文件描述符与文件信息区

每个被使用的文件都在内存中开辟了一个相应的文件信息区,用来存放文件的相关信息(如文件的名字、文件状态及文件当前的位置等)。这些信息是保存在一个结构体变量中的。该结构体类型是由系统声明的,取名 FILE

每当打开一个文件的时候,系统会根据文件的情况自动创建一个 FILE 结构的变量,并填充其中的信息,使用者不必关心细节。一般都是通过一个 FILE 的指针来维护这个 FILE 结构的变量,这样使用起来更加方便。

6.15 文件指针的位置

文件指针可以指向文件的任意位置,通常用来记录下一次读取或写入的位置。可以通过一些函数来移动文件指针的位置,如 fseek 函数和 rewind 函数。可以通过一些函数来获取当前文件指针的位置,如 ftell 函数。

6.16 文件的打开和关闭

在使用文件之前应该打开文件,使用完之后应该关闭文件。ANSI C 规定使用 fopen 来打开文件,用 fclose 来关闭文件。

文件打开方式 mode 参数说明:

  • "r":只读模式,打开一个已经存在的文本文件,用于输入。
  • "w":只写模式,打开一个文本文件用于输出,如果文件已存在则清空原有内容,如果文件不存在则创建新文件。
  • "a":追加模式,打开一个文本文件用于在文件尾部追加数据,如果文件不存在则创建新文件。
  • "rb":只读模式,打开一个二进制文件用于输入。
  • "wb":只写模式,打开一个二进制文件用于输出,如果文件已存在则清空原有内容,如果文件不存在则创建新文件。
  • "ab":追加模式,打开一个二进制文件用于在文件尾部追加数据,如果文件不存在则创建新文件。
  • "r+":读写模式,打开一个文本文件用于读写,文件必须已存在。
  • "w+":读写模式,打开一个文本文件用于读写,如果文件已存在则清空原有内容,如果文件不存在则创建新文件。
  • "a+":读写模式,打开一个文本文件用于读写,文件不存在则创建新文件,所有写入操作都追加到文件尾部。
  • "rb+":读写模式,打开一个二进制文件用于读写,文件必须已存在。
  • "wb+":读写模式,打开一个二进制文件用于读写,如果文件已存在则清空原有内容,如果文件不存在则创建新文件。
  • "ab+":读写模式,打开一个二进制文件用于读写,文件不存在则创建新文件,所有写入操作都追加到文件尾部。

6.17 文件的读写操作

文件的读写操作可以通过一系列函数来完成,如 freadfwritefgetcfputcfgetsfputs 等。这些函数通常使用缓冲机制来提高性能。

6.18 文件定位

文件定位可以通过 fseek 函数来实现,该函数允许移动文件指针到文件中的任意位置。ftell 函数可以获取文件指针的当前位置。

fseek 函数参数说明:

  • stream:指向 FILE 结构的指针。
  • offset:偏移量,可以是正数或负数。
  • whence:定位基准点,可以是 SEEK_SET(文件开头)、SEEK_CUR(当前文件位置)或 SEEK_END(文件末尾)。

示例代码:

#include <stdio.h>
#include <errno.h>
#include <string.h>int main() {// 打开文件FILE *file = fopen("example.txt", "r+");if (file == NULL) {fprintf(stderr, "打开文件失败: %s\n", strerror(errno));return 1;}// 移动文件指针到文件开头if (fseek(file, 0, SEEK_SET) != 0) {fprintf(stderr, "移动文件指针失败: %s\n", strerror(errno));fclose(file);return 1;}// 获取文件指针的当前位置long position = ftell(file);if (position == -1) {fprintf(stderr, "获取文件指针位置失败: %s\n", strerror(errno));fclose(file);return 1;}printf("文件指针位置: %ld\n", position);// 移动文件指针到文件末尾if (fseek(file, 0, SEEK_END) != 0) {fprintf(stderr, "移动文件指针失败: %s\n", strerror(errno));fclose(file);return 1;}// 获取文件指针的当前位置position = ftell(file);if (position == -1) {fprintf(stderr, "获取文件指针位置失败: %s\n", strerror(errno));fclose(file);return 1;}printf("文件指针位置: %ld\n", position);fclose(file);return 0;
}

6.19 文件错误处理

在进行文件操作时,必须注意处理可能出现的错误。可以使用 ferrorclearerr 函数来帮助诊断和清除错误状态。

示例代码:

#include <stdio.h>
#include <errno.h>
#include <string.h>int main() {// 打开文件FILE *file = fopen("nonexistent.txt", "r");if (file == NULL) {fprintf(stderr, "打开文件失败: %s\n", strerror(errno));return 1;}char buffer[100];size_t bytes_read;// 读取文件bytes_read = fread(buffer, 1, sizeof(buffer), file);if (ferror(file)) {fprintf(stderr, "读取文件失败: %s\n", strerror(errno));fclose(file);return 1;}// 清除错误状态clearerr(file);fclose(file);return 0;
}

文件映射

文件映射是一种高效的数据处理方法,它将文件内容直接映射到进程的虚拟地址空间,使得对文件的操作就像对内存的操作一样简单。文件映射通常通过 mmap 函数来实现。

6.20 使用 mmap 进行文件映射

mmap 函数可以将文件或其他对象映射到内存,映射的内存区域可以直接被读写。

示例代码:

#include <stdio.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>int main() {// 打开文件int fd = open("largefile.dat", O_RDONLY);if (fd == -1) {perror("打开文件失败");return 1;}// 获取文件大小struct stat st;if (fstat(fd, &st) == -1) {perror("获取文件大小失败");close(fd);return 1;}// 映射文件到内存void *addr = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);if (addr == MAP_FAILED) {perror("映射文件失败");close(fd);return 1;}// 处理映射内存// ...// 解映射内存if (munmap(addr, st.st_size) == -1) {perror("解映射内存失败");close(fd);return 1;}// 关闭文件if (close(fd) == -1) {perror("关闭文件失败");return 1;}return 0;
}

总结

本文详细介绍了C语言文件操作中的库函数和系统调用,解释了它们的工作原理、区别和联系,并通过实际示例展示了如何使用这些函数。通过本文的学习,读者应能全面理解C语言文件操作的底层机制,为编写高效、可靠的程序提供有力支持。

希望本文能够帮助读者深入理解和应用C语言中的文件操作技术。如果您有任何进一步的问题或建议,请随时留言交流。

相关文章:

深入C语言文件操作:从库函数到系统调用

引言 文件操作是编程中不可或缺的一部分&#xff0c;尤其在C语言中&#xff0c;文件操作不仅是处理数据的基本手段&#xff0c;也是连接程序与外部世界的重要桥梁。C语言提供了丰富的库函数来处理文件&#xff0c;如 fopen、fclose、fread、fwrite 等。然而&#xff0c;这些库…...

【Linux】shell脚本二

2、接收用户的参数 shell脚本已经内设了用于接收用户输入参数的变量&#xff0c;变量之间可以使用空格隔开。 如&#xff1a;./test.sh one two three four $0&#xff1a;对应的是当前shell脚本程序的名称&#xff0c;即test.sh$#&#xff1a;对应的是总共有几个参数&#…...

从万维网到人工智能:改变生活的11项技术里程碑

1984 年 1 月 24 日&#xff0c;苹果公司推出了 Macintosh 128K&#xff0c;从此永远改变了个人电脑的面貌。 史蒂夫・乔布斯&#xff08;Steve Jobs&#xff09;这款小巧且用户友好的电脑向全世界引入了图形用户界面&#xff0c;标志着个人技术发展历程中的一个关键时刻。 从…...

Hyperledger Fabric 2.x 环境搭建

Hyperledger Fabric 是一个开源的企业级许可分布式账本技术&#xff08;Distributed Ledger Technology&#xff0c;DLT&#xff09;平台&#xff0c;专为在企业环境中使用而设计&#xff0c;与其他流行的分布式账本或区块链平台相比&#xff0c;它有一些主要的区别。 环境准备…...

【Maven】自定义Maven插件

场景&#xff1a; 1、自定义一个插件目标 timer&#xff0c;用于显示当前日期时间。 2、将 timer 绑定到 validate 阶段。 调研 1、maven-clean-plugin 下载 maven-clean-plugin 插件的源码&#xff0c;在本地使用 IDEA 打开 可以看到&#xff0c;maven-clean-plugin 插件是…...

修改vscode中emmet中jsx和tsx语法中className的扩展符号从单引号到双引号 - HTML代码补全 - 单引号双引号

效果图 实现步骤 文件 > 首选项 > 设置搜索“”在settings.json中修改&#xff0c;增加 "emmet.syntaxProfiles": {"html": {"attr_quotes": "single"},"jsx": {"attr_quotes": "double","…...

数据结构day3作业

一、完整功能【顺序表】的创建 【seqList.h】 #ifndef __SEQLIST_H__ #define __SEQLIST_H__#include <stdio.h> #include <string.h> #include <stdlib.h>//宏定义&#xff0c;线性表的最大容量 #define MAX 30//类型重定义&#xff0c;表示要存放数据的类…...

pydub AudioSegment实现音频重采样 - python 实现

DataBall 助力快速掌握数据集的信息和使用方式&#xff0c;会员享有 百种数据集&#xff0c;持续增加中。 需要更多数据资源和技术解决方案&#xff0c;知识星球&#xff1a; “DataBall - X 数据球(free)” -------------------------------------------------------------…...

C++多线程常用方法

在 C 中&#xff0c;线程相关功能主要通过头文件提供的类和函数来实现&#xff0c;以下是一些常用的线程接口方法和使用技巧&#xff1a; std::thread类 构造函数&#xff1a; 可以通过传入可调用对象&#xff08;如函数指针、函数对象、lambda 表达式等&#xff09;来创建一…...

【网络安全】Web Timing 和竞争条件攻击:揭开隐藏的攻击面

Web Timing 和竞争条件攻击&#xff1a;揭开隐藏的攻击面 在传统的 Web 应用中&#xff0c;漏洞的发现和利用通常相对容易理解。如果代码存在问题&#xff0c;我们可以通过发送特定输入来强制 Web 应用执行非预期的操作。这种情况下&#xff0c;输入和输出之间往往有直接关系&…...

12月最新编程语言排行榜

“岁末将至&#xff0c;2024年的编程世界又发生了哪些变化&#xff1f;是Python依然稳坐王座&#xff0c;还是有新语言杀出重围&#xff1f;让我们一起看看12月最新编程语言排行榜&#xff0c;寻找未来技术的风向标。” 今年&#xff0c;哪些编程语言成为行业焦点&#xff1f;…...

迭代器模式

迭代器模式 迭代器模式&#xff08;Iterator Pattern&#xff09;是一种行为设计模式&#xff0c;它提供了一种方法来访问一个聚合对象中的各个元素&#xff0c;而又不暴露其内部的表示。这种模式允许你逐个访问对象中的元素&#xff0c;而无需知道其底层的数据结构。迭代器模…...

探秘 WB 实验:AI 助力攻克操作难关

在生物学研究的浩瀚领域中&#xff0c;WB 实验犹如一座关键的灯塔&#xff0c;照亮了我们探索蛋白质世界的道路。今天&#xff0c;就让我们一同深入了解 WB 实验的全貌&#xff0c;以及 AI 如何在其中发挥神奇作用&#xff0c;帮助我们应对实际操作中的重重挑战。 WB 实验&…...

labelimg使用指南

YOLOv8目标检测(一)_检测流程梳理&#xff1a;YOLOv8目标检测(一)_检测流程梳理_yolo检测流程-CSDN博客 YOLOv8目标检测(二)_准备数据集&#xff1a;YOLOv8目标检测(二)_准备数据集_yolov8 数据集准备-CSDN博客 YOLOv8目标检测(三)_训练模型&#xff1a;YOLOv8目标检测(三)_训…...

车载终端_智能车载终端定制_农机/出租车/叉车/驾培车载终端MTK方案

车载终端集成了先进的技术和卓越的性能&#xff0c;采用了联发科的高效低功耗ARM处理器&#xff0c;具备八核架构&#xff0c;主频高达2.0GHz&#xff0c;基于12nm制程工艺&#xff0c;不仅性能强劲&#xff0c;而且功耗控制出色。基本配置为4GB内存与64GB存储&#xff0c;用户…...

Unity中Pico实现透视

1.参照Pico官方【透视 | PICO 开发者平台】文档设置。 2.额外的需要将主相机的post processing禁用。...

elk部署与实战案例

**ELK Stack** 是一个非常强大的日志处理和分析平台&#xff0c;由 **Elasticsearch**、**Logstash** 和 **Kibana** 三个组件组成。它被广泛应用于日志收集、搜索、分析和可视化。ELK 可以处理大量数据&#xff0c;并帮助用户从中提取有价值的信息。以下是一个从部署到实际应用…...

Isaac Gym, Sim, Lab

本文仅为个人学习笔记&#xff0c;文章参考请见参考资料部分&#xff0c;主要目的是进行多场景并行仿真测试&#xff0c;笔记中大部分内容都是针对于这个目标。 参考资料 常见问题 — Isaac Lab 文档 https://github.com/isaac-sim/IsaacLab 一. Gym, Sim, Lab 之间的关系 Is…...

活着就好20241217

亲爱的朋友们&#xff0c;大家早上好&#xff01;&#x1f31e; 今天是17号&#xff0c;星期二&#xff0c;2024年12月的第十七天&#xff0c;同时也是第50周的第八天&#xff0c;农历甲辰[龙]年十一月初十三日。在这晨光熹微的美好时刻&#xff0c;愿那温暖而明媚的阳光轻轻拂…...

第十六章:IO流 (java.io包中)

一、理解 1. 简单而言&#xff1a;流就是内存与存储设备之间传输数据的通道、管道。 2. 分类&#xff1a; (1) 按方向 ( 以 JVM 虚拟机为参照物 ) 【重点】 输入流&#xff1a;将 < 存储设备 > 中的内容读入到 < 内存 > 中。 输出流&#xff1a;将 < 内…...

Introduction to NoSQL Systems

What is NoSQL NoSQL database are no-tabular非數據表格 database that store data differently than relational tables 其數據的存儲方式與關係型表格不同 Database that provide a mechanism機制 for data storage retrieval 檢索 that is modelled in means other than …...

【JVM】JVM基础教程(四)

上一章&#xff1a;【JVM】JVM基础教程&#xff08;三&#xff09;-CSDN博客 目录 自动垃圾回收 方法区的回收 方法区回收条件 手动触发回收 堆回收 如何判断堆上的对象可以回收&#xff1f; 可以给对象引用赋值null&#xff0c;切断引用 引用计数法 循环引用缺点 查…...

前端实现在线预览excel文件

在前端开发中&#xff0c;经常会遇到需要在线预览各种文件的需求。本文将介绍如何使用前端技术实现在线预览 Excel 文件的功能。 一、基于微软office服务的excel预览 获取要预览的 Excel 文件的 URL&#xff08;例如存储在 OneDrive 或 SharePoint 上的文件&#xff09;。 使…...

Python 写的《桌面时钟》屏保

原代码&#xff1a; # 日历式时钟 # 导入所需的库 # 作者&#xff1a;Hoye # 日期&#xff1a;2024年12月16日 # 功能&#xff1a;显示当前日期、星期、时间&#xff0c;并显示模拟时钟 import tkinter as tk from tkinter import ttk import time import math import sysdef …...

计算机视觉单阶段实例分割实践指南与综述

概述 原文地址&#xff1a;https://towardsdatascience.com/single-stage-instance-segmentation-a-review-1eeb66e0cc49 实例分割是一项具有挑战性的计算机视觉任务&#xff0c;需要预测对象实例及其每像素分割掩码。这使其成为语义分割和目标检测的混合体。 自 Mask R-CNN …...

Axios结合Typescript 二次封装完整详细场景使用案例

Axios 是一个基于 promise 的 HTTP 客户端&#xff0c;用于浏览器和 node.js。二次封装 Axios 主要是为了统一管理 HTTP 请求&#xff0c;例如设置统一的请求前缀、头部、超时时间&#xff0c;统一处理请求和响应的格式&#xff0c;以及错误处理等。 以下是一个使用 TypeScrip…...

C++面试:HTTP1.0/1.1,HTTP2.0,HTPP3.0的区别

1.你对HTTP1.0/1.1&#xff0c;HTTP2.0&#xff0c;HTPP3.0有什么了解&#xff1f; 答&#xff1a;HTTP1.0&#xff1a; ①属于无连接式&#xff0c;每次发送HTTP请求都需要建立TCP连接。 ②会造成发送时的对头阻塞&#xff0c;当上一个请求没有应答&#xff0c;当前的请求就会…...

使用 Docker Compose 部署 Redis 主从与 Sentinel 高可用集群

文章目录 使用 Docker Compose 部署 Redis 主从与 Sentinel 高可用集群Redis 主从架构简介Redis Sentinel 简介配置文件1. 主节点配置 (redis-master.conf)2. 从节点配置 (redis-slave1.conf 和 redis-slave2.conf)redis-slave1.confredis-slave2.conf3. Sentinel 配置 (sentin…...

【Java】4、虚拟机 JVM

目录 Java内存区域详解(重点) JVM垃圾回收详解(重点) 类文件结构详解 类加载过程详解 类加载器详解(重点) 最重要的JVM参数总结 JDK监控和故障处理工具总结 JVM线上问题排查和性能调优案例 参考&#xff1a; JVM 核心技术 32 讲 深入浅出 Java 虚拟机...

Vue3之组合式API详解

Vue 3引入了一种新的API风格——组合式API&#xff08;Composition API&#xff09;&#xff0c;旨在提升组件的逻辑复用性和可维护性。本文将详细阐述Vue 3中的组合式API&#xff0c;包括其定义、特点、使用场景、优势等&#xff0c;并给出具体的示例代码。 一、定义 组合式…...

Flutter编译Module was compiled with an incompatible version of Kotlin错误解决

文章目录 编译报错如下解决方法修复方案 编译报错如下 e: C:/Users/YUAN/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib/1.9.20/e58b4816ac517e9cc5df1db051120c63d4cde669/kotlin-stdlib-1.9 .20.jar!/META-INF/kotlin-stdlib-jdk8.kotlin_module:…...

Uniapp插件如何通过NFC读取多种证卡信息?

nfc读卡uniapp插件&#xff0c;由中软高科进行开发&#xff0c;主要是通过NFC读取居民身份证、港澳台居住证、外国人居住证、护照等证卡的信息。经过多个版本的升级更新&#xff0c;目前性能已趋于稳定&#xff0c;并且读卡速度较之最初版本有了大的提升。 注意事项 测试使用的…...

本地docker镜像改名字

如果你想修改本地 Docker 镜像的名字&#xff0c;可以通过创建该镜像的新标签&#xff08;tag&#xff09;来实现。Docker 中没有直接修改镜像名字的命令&#xff0c;但可以通过重新打标签的方式实现类似的效果。以下是具体步骤&#xff1a; 查看当前镜像&#xff1a; docker…...

VS Code 远程连接 SSH 服务器

文章目录 一、安装 Remote - SSH 扩展并连接远程主机二、免密连接远程主机1. 生成 SSH 密钥对2. 将公钥复制到远程服务器3. 配置 SSH 客服端4. 连接测试 随着技术的不断迭代更新&#xff0c;在 Linux 系统中使用 Vim、nano 等基于 Shell 终端的编辑器&#xff08;我曾经也是个 …...

艾体宝案例丨CircleCI 助力 ANA Systems 打造高效 CI/CD 模型

在现代软件开发领域&#xff0c;效率和可靠性是企业在竞争中取胜的关键。本文将深入探讨 ANA Systems 如何通过引入业界领先的 CI/CD 平台——CircleCI&#xff0c;克服传统开发流程的瓶颈&#xff0c;实现开发运营效率的全面提升。同时&#xff0c;本文还将详细解析 CircleCI …...

vue 上传组件 vxe-upload 实现拖拽调整顺序

vue 上传组件 vxe-upload 实现拖拽调整顺序&#xff0c;通过设置 drag-sort 参数就可以启用拖拽排序功能 官网&#xff1a;https://vxeui.com/ 图片拖拽排序 <template><div><vxe-upload v-model"imgList" mode"image" multiple drag-sor…...

Elasticsearch的一些介绍

你想问的可能是 **Elasticsearch**&#xff0c;以下是关于它的一些介绍&#xff1a; ### 概述 Elasticsearch是一个基于Apache Lucene库构建的开源分布式搜索和分析引擎&#xff0c;采用Java语言编写&#xff0c;具有高性能、可扩展性和易用性等特点&#xff0c;可用于各种数据…...

从源码构建安装Landoop kafka-connect-ui

背景 部署Landoop kafka-connect-ui最简单的办法还是通过docker来部署&#xff0c;我们之前的kafka-connect-ui就是通过docker部署的&#xff0c;但是&#xff0c;最近发现个问题&#xff1a;当使用docker部署且防火墙使用的是firewalld的情况下&#xff0c;就会出现端口冲突。…...

MybatisPlus-扩展功能

代码生成 在使用MybatisPlus以后&#xff0c;基础的Mapper、Service、PO代码相对固定&#xff0c;重复编写也比较麻烦。因此MybatisPlus官方提供了代码生成器根据数据库表结构生成PO、Mapper、Service等相关代码。只不过代码生成器同样要编码使用&#xff0c;也很麻烦。 这里…...

发布/部署WebApi服务器(IIS+.NET8+ASP.NETCore)

CS软件授权注册系统-发布/部署WebApi服务器(IIS.NET8ASP.NETCore) 目录 本文摘要VS2022配置发布VS2022发布WebApiIIS服务器部署WebApi 将程序文件复制到云服务器添加网站配置应用程序池配置dns域名配置端口阿里云ECS服务器配置19980端口配置https协议 (申请ssl证书)测试WebAp…...

【2025最新计算机毕业设计】基于SpringBoot+Vue城市中小学体育场馆预约系统【提供源码+答辩PPT+文档+项目部署】

一、项目技术架构&#xff1a; 本项目是一款城市中小学体育场馆预约系统的设计与实现。 该SpringBootVue的城市中小学体育场馆预约系统&#xff0c;后端采用SpringBoot架构&#xff0c;前端采用VueElementUI实现页面的快速开发&#xff0c;并使用关系型数据库MySQL存储系统运行…...

Spring Security 6 系列之二 - 基于数据库的用户认证和认证原理

之所以想写这一系列&#xff0c;是因为之前工作过程中使用Spring Security&#xff0c;但当时基于spring-boot 2.3.x&#xff0c;其默认的Spring Security是5.3.x。之后新项目升级到了spring-boot 3.3.0&#xff0c;结果一看Spring Security也升级为6.3.0&#xff0c;关键是其风…...

vue中打包dist文件内static 和 assets 的区别

背景 在Vue.js项目中&#xff0c;assets 和 static 是两个用于存放静态资源的文件夹&#xff0c;但它们在使用方式和处理机制上有所不同 用途 assets: assets 文件夹通常用于存放那些需要在构建过程中被Webpack处理的静态资源。这些资源可以包括图片、字体、样式文件&#…...

Big Model weekly | 第49期

点击蓝字 关注我们 AI TIME欢迎每一位AI爱好者的加入&#xff01; 01 Magnetic Preference Optimization: Achieving Last-iterate Convergence for Language Models Alignment 自我对弈方法在多个领域增强模型能力方面展现出了显著的成功。在基于人类反馈的强化学习&#xff0…...

Node.js内置模块

1.内置模块 Node.js的中文网参考手册:https://nodejs.cn//api 帮助文档 API文档:查看对应的模块,左边是模块,右边是模块的成员 源码:https://github.com/nodejs/node/tree/main/lib 查看 例如: http.js 创建web服务器的模块 -->进入源码中,搜索…...

使用Nexus3搭建npm私有仓库

一、npm介绍 npm的全称是Node Package Manager&#xff0c;它是一个开放源代码的命令行工具&#xff0c;用于安装、更新和管理Node.js模块。npm是Node.js的官方模块管理器&#xff0c;它允许用户从一个集中的仓库中下载和安装公共的Node.js模块&#xff0c;并将这些模块集成到…...

MySQL学习之表操作

MySQL学习之表操作 基础命令 查询当前所在数据库的所有表 show tables;查看指定的表结构, 可以查看到指定表的字段&#xff0c;字段的类型、是否可以为NULL&#xff0c;是否存在默认值等信息 mysql> desc user; ----------------------------------------------- | Field |…...

C语言学习day22:ReadProcessMemory函数/游戏内存数据读取工具开发

简言&#xff1a; ReadProcessMemory函数是 Windows API 中的一个函数&#xff0c;用于从目标进程的虚拟内存空间中读取数据。这个函数非常有用&#xff0c;尤其是在进行内存分析、调试、或某些类型的逆向工程时。 ReadProcessMemory函数 函数原型 BOOL ReadProcessMemory(…...

Linux虚拟文件系统

参考&#xff1a;深入分析LINUX内核源码 深入分析Linux内核源码 (kerneltravel.net) 作为一个最著名的自由软件&#xff0c;Linux 确实名不虚传&#xff0c;几乎处处体现了“自由”&#xff0c;你可以编译适合自己系统要求的内核&#xff0c;或者轻松添加别人开发的新的模块。只…...

OpenIPC开源FPV之Adaptive-Link天空端代码解析

OpenIPC开源FPV之Adaptive-Link天空端代码解析 1. 源由2. 框架代码3. 报文处理3.1 special报文3.2 普通报文 4. 工作流程4.1 Profile 竞选4.2 Profile 研判4.3 Profile 应用 5. 总结6. 参考资料7. 补充资料7.1 RSSI 和 SNR 的物理含义7.2 信号质量加权的理论依据7.3 实际应用中…...