Linux系统程序设计--2. 文件I/O
文件I/O
标准C的I/O
FILE结构体
- 下面只列出了5个成员



- 可以观察到,有些函数没有FILE类型的结构体指针例如printf主要是一些标准输出,因为其内部用到了stdin,stdout,stderr
- 查找文件所在的位置:
find \ -name stat.h - 查找头文件所在的位置。可以使用gcc
#include <sys/stat.h>int main() {return 0; }gcc -M test.c

代码文件
src.c的目标文件
bin- 编译链接生成的可执行文件
obj- 存放生成的.o`的目标文件
include- 存储头文件
缓冲
缓冲类型

- 全缓冲(Fully Buffered):
- 数据被写入缓冲区,当缓冲区满或显式调用
fflush时才写入目标。 - 通常用于文件I/O,尤其是磁盘文件。
- 数据被写入缓冲区,当缓冲区满或显式调用
- 行缓冲(Line Buffered):
- 数据在遇到换行符时被写入目标。
- 通常用于终端输入输出(如标准输入
stdin和标准输出stdout)。
#include<stdio.h>
#include<unistd.h>int main(void)
{printf("Hello Iotak\n");while(1){sleep(1);}return 0;
}
sleep函数不是标准C库的一部分,而是POSIX标准的一部分
在大多数Unix-like系统(如Linux和macOS)上,sleep函数定义在unistd.h头文件中。
在Windows上,你可以使用Sleep函数(注意首字母大写),它定义在windows.h头文件中。
- 无缓冲(Unbuffered):
- 每次I/O操作直接与目标交互,没有中间缓冲区。
- 通常用于标准错误
stderr。
常见的I/O函数及其缓冲特性
- 标准输入/输出函数:
printf、puts、putchar:默认行缓冲(对于终端),全缓冲(对于文件)。scanf、getchar、gets:默认行缓冲(对于终端),全缓冲(对于文件)。
- 文件操作函数:
fprintf、fputs、fputc:默认全缓冲。fscanf、fgetc、fgets:默认全缓冲。fread、fwrite:默认全缓冲。fclose、fflush:显式刷新缓冲区。setbuf、setvbuf:允许手动设置缓冲方式和缓冲区大小。
特殊情况
- 标准错误
stderrstderr默认是无缓冲的,这样可以确保错误信息立即显示,不会因为缓冲而延迟。- 使用
setvbuf可以改变stderr的缓冲方式。
示例
默认缓冲行为
#include <stdio.h>int main() {printf("This is a test.\n"); // 行缓冲,遇到换行符会刷新fprintf(stderr, "This is an error message.\n"); // 无缓冲,立即显示return 0;
}
手动设置缓冲方式
#include <stdio.h>int main() {char buffer[1024];setvbuf(stdout, buffer, _IOFBF, sizeof(buffer)); // 设置stdout为全缓冲printf("This is a test."); // 不会立即显示,因为没有换行符fflush(stdout); // 显式刷新缓冲区return 0;
}
总结
- 标准输入/输出:通常行缓冲(对于终端)或全缓冲(对于文件)。
- 标准错误:默认无缓冲。
- 文件操作:默认全缓冲。
- 手动控制:可以使用
setbuf和setvbuf函数手动设置缓冲方式和缓冲区大小。
标准输入/输出函数
1. int printf(const char *format, ...);
-
头文件:
<stdio.h> -
功能:将格式化的数据写入到标准输出(通常是屏幕)。
-
参数:
const char *format:格式控制字符串。...:可变参数列表,根据格式字符串中的占位符提供相应的值。
-
返回值:成功时返回打印的字符数;失败时返回一个负值。
-
例子:
#include <stdio.h> int main() {printf("Hello, World!\n");return 0; }
2. int scanf(const char *format, ...);
-
头文件:
<stdio.h> -
功能:从标准输入读取格式化输入。
-
参数:
const char *format:格式控制字符串。...:可变参数列表,通常是指向变量的指针,用于存储读取的值。
-
返回值:成功时返回成功读取并赋值的数据项数量;到达文件结束或遇到错误时返回EOF。
-
例子:
#include <stdio.h> int main() {int num;printf("Enter an integer: ");scanf("%d", &num);printf("You entered: %d\n", num);return 0; }
3. int puts(const char *s);
-
头文件:
<stdio.h> -
功能:将字符串写入标准输出,自动添加换行符。
-
参数:
const char *s:要写入的字符串。
-
返回值:成功时返回非负值;如果发生错误,则返回EOF。
-
例子:
#include <stdio.h> int main() {puts("Hello, World!");return 0; }
4. char *gets(char *s);
-
头文件:
<stdio.h> -
功能:从标准输入读取一行字符串(不推荐使用,存在缓冲区溢出风险)。
-
参数:
char *s:指向存储读取字符串的缓冲区的指针。
-
返回值:成功时返回指向字符串的指针;如果到达文件末尾或发生错误,则返回NULL。
-
例子:
#include <stdio.h> int main() {char buffer[100];printf("Enter a line: ");gets(buffer); // 不推荐使用printf("You entered: %s\n", buffer);return 0; }
5. int getchar(void);
-
头文件:
<stdio.h> -
功能:从标准输入读取下一个可用字符。
-
参数:无。
-
返回值:成功时返回读取的字符;如果到达文件结束或发生错误,则返回EOF。
-
例子:
#include <stdio.h> int main() {int ch;printf("Press any key and then press enter: ");ch = getchar();printf("You pressed: %c\n", ch);return 0; }
6. int putchar(int c);
-
头文件:
<stdio.h> -
功能:将指定的字符写入到标准输出。
-
参数:
int c:要写入的字符。
-
返回值:成功时返回写入的字符;如果发生错误,则返回EOF。
-
例子:
#include <stdio.h> int main() {putchar('A');return 0; }
文件操作函数
7. FILE *fopen(const char *path, const char *mode);
-
头文件:
<stdio.h> -
功能:打开或创建一个文件,并返回一个指向该文件的FILE类型指针。
-
参数:
const char *path:文件路径。const char *mode:打开模式(如"r"表示只读,"w"表示写入等)。
-
返回值:成功时返回指向文件的指针;如果打开失败,则返回NULL。
-
例子:
#include <stdio.h> int main() {FILE *file = fopen("example.txt", "r");if (file == NULL) {printf("Failed to open file.\n");return 1;}fclose(file);return 0; }
8. int fclose(FILE *stream);
-
头文件:
<stdio.h> -
功能:关闭一个已打开的文件流。
-
参数:
FILE *stream:指向文件流的指针。
-
返回值:成功时返回0;如果发生错误,则返回EOF。
-
例子:
#include <stdio.h> int main() {FILE *file = fopen("example.txt", "r");if (file == NULL) {printf("Failed to open file.\n");return 1;}fclose(file);return 0; }
9. int fprintf(FILE *stream, const char *format, ...);
-
头文件:
<stdio.h> -
功能:将格式化的数据写入指定的流。
-
参数:
FILE *stream:指向文件流的指针。const char *format:格式控制字符串。...:可变参数列表,根据格式字符串中的占位符提供相应的值。
-
返回值:成功时返回打印的字符数;失败时返回一个负值。
-
例子:
#include <stdio.h> int main() {FILE *file = fopen("test.txt", "w");if (file == NULL) {printf("Error opening file.\n");return 1;}fprintf(file, "This is a test.\n");fclose(file);return 0; }
10. int fscanf(FILE *stream, const char *format, ...);
-
头文件:
<stdio.h> -
功能:从指定的流读取格式化输入。
-
参数:
FILE *stream:指向文件流的指针。const char *format:格式控制字符串。...:可变参数列表,通常是指向变量的指针,用于存储读取的值。
-
返回值:成功时返回成功读取并赋值的数据项数量;到达文件结束或遇到错误时返回EOF。
-
例子:
#include <stdio.h> int main() {FILE *file = fopen("test.txt", "r");if (file == NULL) {printf("Error opening file.\n");return 1;}char str[100];fscanf(file, "%s", str);printf("Read from file: %s\n", str);fclose(file);return 0; }
11. char *fgets(char *str, int n, FILE *stream);
-
头文件:
<stdio.h> -
功能:从流中读取一行(直到换行符或达到指定长度减一)。
-
参数:
char *str:指向存储读取字符串的缓冲区的指针。int n:要读取的最大字符数(包括终止的空字符)。FILE *stream:指向文件流的指针。
-
返回值:成功时返回指向字符串的指针;如果到达文件末尾或发生错误,则返回NULL。
-
例子:
#include <stdio.h> int main() {char buffer[100];FILE *file = fopen("example.txt", "r");if (file == NULL) {printf("Failed to open file.\n");return 1;}fgets(buffer, sizeof(buffer), file);printf("Read from file: %s", buffer);fclose(file);return 0; }
12. int fputs(const char *str, FILE *stream);
-
头文件:
<stdio.h> -
功能:向指定的流写入一个字符串(不包括终止的空字符)。
-
参数:
const char *str:要写入的字符串。FILE *stream:指向文件流的指针。
-
返回值:成功时返回非负值;如果发生错误则返回EOF。
-
例子:
#include <stdio.h> int main() {FILE *file = fopen("test.txt", "w");if (file == NULL) {printf("Error opening file.\n");return 1;}const char *message = "This is a message.";fputs(message, file);fclose(file);return 0; }
13. int fgetc(FILE *stream);
-
头文件:
<stdio.h> -
功能:从指定的流中读取下一个字符。
-
参数:
FILE *stream:指向文件流的指针。
-
返回值:成功时返回读取的字符;如果到达文件结束或发生错误,则返回EOF。
-
例子:
#include <stdio.h> int main() {FILE *file = fopen("example.txt", "r");if (file == NULL) {printf("Failed to open file.\n");return 1;}int ch;while ((ch = fgetc(file)) != EOF) {putchar(ch);}fclose(file);return 0; }
14. int fputc(int c, FILE *stream);
-
头文件:
<stdio.h> -
功能:将指定的字符写入到指定的流。
-
参数:
int c:要写入的字符。FILE *stream:指向文件流的指针。
-
返回值:成功时返回写入的字符;如果发生错误,则返回EOF。
-
例子:
#include <stdio.h> int main() {FILE *file = fopen("example.txt", "w");if (file == NULL) {printf("Failed to open file.\n");return 1;}fputc('A', file);fclose(file);return 0; }
15. int fseek(FILE *stream, long offset, int whence);
-
头文件:
<stdio.h> -
功能:设置文件流的位置指针。
-
参数:
FILE *stream:指向文件流的指针。long offset:相对于whence的偏移量。int whence:位置基准点(如SEEK_SET表示文件开头,SEEK_CUR表示当前位置,SEEK_END表示文件结尾)。
-
返回值:成功时返回0;如果发生错误,则返回非零值。
-
例子:
#include <stdio.h> int main() {FILE *file = fopen("example.txt", "r+");if (file == NULL) {printf("Failed to open file.\n");return 1;}fseek(file, 5, SEEK_SET); // 移动到文件开头后的第5个字节fclose(file);return 0; }
16. long ftell(FILE *stream);
-
头文件:
<stdio.h> -
功能:获取文件流的当前读写位置。
-
参数:
FILE *stream:指向文件流的指针。
-
返回值:成功时返回当前的位置(以字节为单位);如果发生错误,则返回-1L。
-
例子:
#include <stdio.h> int main() {FILE *file = fopen("example.txt", "r");if (file == NULL) {printf("Failed to open file.\n");return 1;}fseek(file, 5, SEEK_SET); // 移动到文件开头后的第5个字节long pos = ftell(file);printf("Current position: %ld\n", pos);fclose(file);return 0; }
17. void rewind(FILE *stream);
-
头文件:
<stdio.h> -
功能:将文件流的位置指针重置到文件开头。
-
参数:
FILE *stream:指向文件流的指针。
-
返回值:无。
-
例子:
#include <stdio.h> int main() {FILE *file = fopen("example.txt", "r");if (file == NULL) {printf("Failed to open file.\n");return 1;}fseek(file, 5, SEEK_SET); // 移动到文件开头后的第5个字节rewind(file); // 重置到文件开头fclose(file);return 0; }
18. int feof(FILE *stream);
-
头文件:
<stdio.h> -
功能:检测文件流是否到达文件结束。
-
参数:
FILE *stream:指向文件流的指针。
-
返回值:如果文件流到达文件结束,则返回非零值;否则返回0。
-
例子:
#include <stdio.h> int main() {FILE *file = fopen("example.txt", "r");if (file == NULL) {printf("Failed to open file.\n");return 1;}int ch;while ((ch = fgetc(file)) != EOF) {putchar(ch);}if (feof(file)) {printf("End of file reached.\n");}fclose(file);return 0; }
19. int ferror(FILE *stream);
-
头文件:
<stdio.h> -
功能:检测文件流是否发生错误。
-
参数:
FILE *stream:指向文件流的指针。
-
返回值:如果文件流发生错误,则返回非零值;否则返回0。
-
例子:
#include <stdio.h> int main() {FILE *file = fopen("nonexistent.txt", "r");if (file == NULL) {printf("Failed to open file.\n");return 1;}int ch;while ((ch = fgetc(file)) != EOF) {if (ferror(file)) {printf("Error reading file.\n");break;}putchar(ch);}fclose(file);return 0; }
20. void clearerr(FILE *stream);
-
头文件:
<stdio.h> -
功能:清除文件流的错误标志和文件结束标志。
-
参数:
FILE *stream:指向文件流的指针。
-
返回值:无。
-
例子:
#include <stdio.h> int main() {FILE *file = fopen("example.txt", "r");if (file == NULL) {printf("Failed to open file.\n");return 1;}int ch;while ((ch = fgetc(file)) != EOF) {if (ferror(file)) {clearerr(file); // 清除错误标志printf("Error cleared.\n");break;}putchar(ch);}fclose(file);return 0; }
21. int remove(const char *filename);
-
头文件:
<stdio.h> -
功能:删除指定的文件。
-
参数:
const char *filename:要删除的文件名。
-
返回值:成功时返回0;如果发生错误,则返回非零值。
-
例子:
#include <stdio.h> int main() {if (remove("example.txt") == 0) {printf("File deleted successfully.\n");} else {printf("Error deleting file.\n");}return 0; }
22. int rename(const char *oldname, const char *newname);
-
头文件:
<stdio.h> -
功能:重命名文件。
-
参数:
const char *oldname:旧文件名。const char *newname:新文件名。
-
返回值:成功时返回0;如果发生错误,则返回非零值。
-
例子:
#include <stdio.h> int main() {if (rename("oldname.txt", "newname.txt") == 0) {printf("File renamed successfully.\n");} else {printf("Error renaming file.\n");}return 0; }
23. void setbuf(FILE *stream, char *buf);
-
头文件:
<stdio.h> -
功能:设置或取消文件流的缓冲区。
-
参数:
FILE *stream:指向文件流的指针。char *buf:缓冲区指针。如果为NULL,则取消缓冲。
-
返回值:无。
-
例子:
#include <stdio.h> int main() {FILE *file = fopen("example.txt", "w");if (file == NULL) {printf("Failed to open file.\n");return 1;}setbuf(file, NULL); // 取消缓冲fprintf(file, "This is a test.\n");fclose(file);return 0; }
24. int setvbuf(FILE *stream, char *buf, int mode, size_t size);
-
头文件:
<stdio.h> -
功能:设置文件流的缓冲方式和大小。
-
参数:
FILE *stream:指向文件流的指针。char *buf:缓冲区指针。如果为NULL,则使用系统分配的缓冲区。int mode:缓冲方式(如_IOFBF表示完全缓冲,_IOLBF表示行缓冲,_IONBF表示不缓冲)。size_t size:缓冲区大小。
-
返回值:成功时返回0;如果发生错误,则返回非零值。
-
例子:
#include <stdio.h> int main() {FILE *file = fopen("example.txt", "w");if (file == NULL) {printf("Failed to open file.\n");return 1;}char buffer[1024];setvbuf(file, buffer, _IOFBF, sizeof(buffer)); // 设置完全缓冲fprintf(file, "This is a test.\n");fclose(file);return 0; }
25. int fflush(FILE *stream);
-
头文件:
<stdio.h> -
功能:刷新文件流的缓冲区。
-
参数:
FILE *stream:指向文件流的指针。如果为NULL,则刷新所有输出流。
-
返回值:成功时返回0;如果发生错误,则返回EOF。
-
例子:
#include <stdio.h> int main() {FILE *file = fopen("example.txt", "w");if (file == NULL) {printf("Failed to open file.\n");return 1;}fprintf(file, "This is a test.\n");fflush(file); // 刷新缓冲区fclose(file);return 0; }
这些函数是标准C语言中最常用的一些I/O函数,涵盖了标准输入/输出和文件操作的基本需求。希望这些信息对你有帮助!如果有任何其他问题或需要进一步的解释,请告诉我。
文件描述符
- 标准IO函数通过
FILE类型的结构体指针,系统IO函数则是通过文件描述符来完成 
文件描述符和文件结构体指针相互的转换

fdopen:将文件描述符转换为文件流,方便使用标准I/O函数进行操作。fileno:将文件流转换为文件描述符,方便使用低级I/O系统调用进行操作。
fdopen 函数
- 函数原型
FILE *fdopen(int fd, const char *mode);
-
参数说明
-
int fd:文件描述符。 -
const char *mode:打开模式(如"r"表示只读,"w"表示写入,"a"表示追加等)。
-
-
所在头文件
<stdio.h>
-
返回值
-
成功时返回指向文件流的指针。
-
失败时返回
NULL。
-
-
简单示例
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>int main() {int fd = open("example.txt", O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);if (fd == -1) {perror("open");return 1;}FILE *fp = fdopen(fd, "r+");if (fp == NULL) {perror("fdopen");close(fd);return 1;}// 使用文件流进行操作const char *message = "Hello, fdopen!";fwrite(message, 1, strlen(message), fp);// 重置文件位置指针rewind(fp);char buffer[100];size_t bytesRead = fread(buffer, 1, sizeof(buffer) - 1, fp);buffer[bytesRead] = '\0';printf("Read from file: %s\n", buffer);fclose(fp); // 关闭文件流,同时关闭文件描述符return 0;
}
fileno 函数
- 函数原型
int fileno(FILE *stream);
-
参数说明
-
FILE *stream:指向文件流的指针。 -
所在头文件
-
<stdio.h> -
返回值
-
成功时返回文件描述符。
-
失败时返回-1。
-
简单示例
#include <stdio.h>
#include <unistd.h>int main() {FILE *fp = fopen("example.txt", "r+");if (fp == NULL) {perror("fopen");return 1;}int fd = fileno(fp);if (fd == -1) {perror("fileno");fclose(fp);return 1;}printf("File descriptor: %d\n", fd);// 使用文件描述符进行操作const char *message = "Hello, fileno!";write(fd, message, strlen(message));// 重置文件位置指针lseek(fd, 0, SEEK_SET);char buffer[100];ssize_t bytesRead = read(fd, buffer, sizeof(buffer) - 1);buffer[bytesRead] = '\0';printf("Read from file: %s\n", buffer);fclose(fp); // 关闭文件流,同时关闭文件描述符return 0;
}
文件I/O的系统调用
- 文件操作函数的头文件一般都需要加上
unistd.h



标准输入/输出函数
1. ssize_t read(int fd, void *buf, size_t count);

-
头文件:
<unistd.h> -
功能:从文件描述符
fd读取最多count个字节到缓冲区buf。 -
参数:
int fd:文件描述符。void *buf:指向存储读取数据的缓冲区的指针。size_t count:要读取的最大字节数。
-
返回值:成功时返回实际读取的字节数;到达文件结束时返回0;发生错误时返回-1。
-
例子:
#include <unistd.h> #include <stdio.h>int main() {char buffer[100];ssize_t bytesRead = read(STDIN_FILENO, buffer, sizeof(buffer) - 1);if (bytesRead == -1) {perror("read");return 1;}buffer[bytesRead] = '\0'; // 确保字符串以空字符结尾printf("Read from stdin: %s\n", buffer);return 0; }
2. ssize_t write(int fd, const void *buf, size_t count);

-
头文件:
<unistd.h> -
功能:将
buf中的count个字节写入文件描述符fd。 -
参数:
int fd:文件描述符。const void *buf:指向要写入的数据的缓冲区的指针。size_t count:要写入的字节数。
-
返回值:成功时返回实际写入的字节数;发生错误时返回-1。
-
例子:
#include <unistd.h> #include <stdio.h>int main() {const char *message = "Hello, World!\n";ssize_t bytesWritten = write(STDOUT_FILENO, message, strlen(message));if (bytesWritten == -1) {perror("write");return 1;}return 0; }
复制案例

- io.h
#ifndef __IO_H__ #define __IO_H__ extern void copy(int fdin,int fdout); #endif - io.c
#include<io.h> #include<errno.h> #include<fcntl.h> #include<unistd.h> #include<stdio.h> #include<string.h> #include<stdlib.h>#define BUFFER_LEN 1024void copy(int fdin,int fdout) {char buffer[BUFFER_LEN];ssize_t size;while((size=read(fdin,buffer,BUFFER_LEN))>0){if(size<0){fprintf(stderr,"read error:%s\n",strerror(errno));exit(1);}else{if(write(fdout,buffer,size)!=size){fprintf(stderr,"read error:%s\n",strerror(errno));exit(1);}}}
gcc obj/io -Iinclude -c src/io.c
- -Iinclude
-
- -c
- 产生目标文件
gcc bin/cp -Iinclude obj/io.o src/cp.c或者gcc bin/cp -Iinclude src/io.c src/cp.c
- cp.c
#include<stdio.h> #include<string.h> #include<stdlib.h> #include<fcntl.h> #include<unistd.h> #include<errno.h> #include"io.h" int main(int argc,char ** argv) {if(argc<3){fprintf(stderr,"usage:%s srcfile destfile \n",argv[0]);exit(1);}int fdin = open(argv[1],O_RDONLY);if(fdin<0){fprintf(stderr,"%s fdin open fails:%s \n",argv[1],strerror(errno));exit(1);}else{printf("%s %d\n",argv[1],fdin);}int fdout = open(argv[2],O_WRONLY|O_CREAT|O_TRUNC,0777);if(fdout<0){fprintf(stderr,"%s fdout open fails:%s \n",argv[2],strerror(errno));exit(1);}else{printf("%s %d\n",argv[2],fdout);}copy(fdin,fdout);close(fdin);close(fdout);return 0; }
文件操作函数
- C库函数的头文件都在
\usr\include下 - -查找头文件所在的位置。可以使用gcc
#include <sys/stat.h>int main() {return 0; }gcc -M test.c
3. int open(const char *pathname, int flags, mode_t mode);

-
头文件:
<fcntl.h>和<sys/stat.h> -
功能:打开或创建一个文件,并返回一个文件描述符。
-
参数:
const char *pathname:文件路径。int flags:打开模式(如O_RDONLY表示只读,O_WRONLY表示只写,O_RDWR表示读写等在头文件<fcntl.h>中定义)。
//例如,创建一个用户可读可写的文件: int fd = open("example.txt", O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
mode_t mode:文件权限(仅在创建文件时使用)。-
mode参数是一个mode_t类型的值,通常由几个权限位按位或(|)组合而成。以下是一些常用的权限位及其说明: -
用户权限:
S_IRUSR:用户读权限(0400)S_IWUSR:用户写权限(0200)S_IXUSR:用户执行权限(0100)
-
组权限:
-S_IRGRP:组读权限(0040)
-S_IWGRP:组写权限(0020)
-S_IXGRP:组执行权限(0010) -
其他用户权限
S_IROTH:其他用户读权限(0004)S_IWOTH:其他用户写权限(0002)S_IXOTH:其他用户执行权限(0001)
-
权限组合
你可以通过按位或运算(|)组合多个权限位来设置文件的权限。例如:-
用户可读可写,组和其他用户不可访问:
mode_t mode = S_IRUSR | S_IWUSR; -
用户可读可写可执行,组可读可执行,其他用户可读:
mode_t mode = S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH;
-
-
以下是一些常见的权限组合示例:
-
用户可读可写:
int fd = open("example.txt", O_CREAT | O_RDWR, S_IRUSR | S_IWUSR); -
用户可读可写可执行:
int fd = open("example.txt", O_CREAT | O_RDWR, S_IRUSR | S_IWUSR | S_IXUSR); -
用户可读可写,组可读,其他用户不可访问:
int fd = open("example.txt", O_CREAT | O_RDWR, S_IRUSR | S_IWUSR | S_IRGRP); -
用户可读可写可执行,组可读可写,其他用户可读:
int fd = open("example.txt", O_CREAT | O_RDWR, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IROTH);
-
-
八进制表示法
- 权限也可以用八进制数字表示,每个数字对应一组权限:
- 第一个数字:用户权限
- 第二个数字:组权限
- 第三个数字:其他用户权限例如:- `0600`:用户可读可写,组和其他用户不可访问- `0755`:用户可读可写可执行,组可读可执行,其他用户可读可执行- `0644`:用户可读可写,组和其他用户可读- 使用八进制表示法设置权限:int fd = open("example.txt", O_CREAT | O_RDWR, 0600);
-
-
返回值:成功时返回文件描述符;如果打开失败,则返回-1。
-
例子:
#include <fcntl.h> #include <sys/stat.h> #include <unistd.h> #include <stdio.h>int main() {int fd = open("example.txt", O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR);if (fd == -1) {perror("open");return 1;}close(fd);return 0; }
creat

creat函数是Linux系统中用于创建文件的一个简化版本的open函数。creat函数的主要特点是它总是创建一个新的文件,并且只以写模式打开文件。如果文件已经存在,creat会截断文件并覆盖其内容。
函数原型
#include <fcntl.h>
int creat(const char *pathname, mode_t mode);
-
参数说明
-
const char *pathname:要创建的文件的路径。 -
mode_t mode:文件的权限模式。
-
-
返回值
-
成功时返回文件描述符(非负整数)。
-
失败时返回-1,并设置
errno以指示错误类型。
-
-
常用的权限模式
权限模式可以用
mode_t类型的值表示,通常由几个权限位按位或(|)组合而成。以下是一些常用的权限位:S_IRUSR:用户读权限(0400)S_IWUSR:用户写权限(0200)S_IXUSR:用户执行权限(0100)S_IRGRP:组读权限(0040)S_IWGRP:组写权限(0020)S_IXGRP:组执行权限(0010)S_IROTH:其他用户读权限(0004)S_IWOTH:其他用户写权限(0002)S_IXOTH:其他用户执行权限(0001)
-
示例
-
#include <fcntl.h> #include <unistd.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <errno.h>int main() {int fd;const char *filename = "example.txt";const char *message = "Hello, creat!";char buffer[100];// 创建文件,权限为用户可读可写fd = creat(filename, S_IRUSR | S_IWUSR);if (fd == -1) {perror("creat");exit(EXIT_FAILURE);}// 写入数据ssize_t bytesWritten = write(fd, message, strlen(message));if (bytesWritten == -1) {perror("write");close(fd);exit(EXIT_FAILURE);}// 重置文件位置指针lseek(fd, 0, SEEK_SET);// 读取数据ssize_t bytesRead = read(fd, buffer, sizeof(buffer) - 1);if (bytesRead == -1) {perror("read");close(fd);exit(EXIT_FAILURE);}buffer[bytesRead] = '\0'; // 确保字符串以空字符结尾printf("Read from file: %s\n", buffer);// 关闭文件close(fd);return 0; }
-
4. int close(int fd);

-
头文件:
<unistd.h> -
功能:关闭一个已打开的文件描述符。
-
参数:
int fd:文件描述符。
-
返回值:成功时返回0;如果发生错误,则返回-1。
5. off_t lseek(int fd, off_t offset, int whence);


- 可以计算文件的大小
printf("%s file length:%ld\n",argv[1],lseek(fdin,0L,SEEK_END));
-
头文件:
<unistd.h> -
功能:设置文件描述符
fd的读写位置。 -
参数:
int fd:文件描述符。off_t offset:相对于whence的偏移量。如 long 或 long longint whence:位置基准点(如SEEK_SET表示文件开头,SEEK_CUR表示当前位置,SEEK_END表示文件结尾)。
-
返回值:成功时返回新的文件位置;如果发生错误,则返回-1。
-
例子:
#include <fcntl.h> #include <sys/stat.h> #include <unistd.h> #include <stdio.h>int main() {int fd = open("example.txt", O_RDWR);if (fd == -1) {perror("open");return 1;}off_t new_pos = lseek(fd, 5, SEEK_SET); // 移动到文件开头后的第5个字节if (new_pos == -1) {perror("lseek");close(fd);return 1;}close(fd);return 0; }
生成空洞文件
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<fcntl.h>
#include<unistd.h>char *buffer = "0123456789";int main(int argc,char *argv[])
{if(argc<2){fprintf(stderr,"parameter is less\n");exit(0);}int fd = open(argv[1],O_CREAT|O_RDWR,0777);if(fd==-1) // 文件打开s失败{fprintf(stderr,"%s file open fail\n",argv[1]);exit(1);}lseek(fd,20L,SEEK_SET);if(write(fd,buffer,strlen(buffer)*sizeof(char))==-1){fprintf(stderr,"write error %s\n",argv[1]);exit(1);}return 0;
}
- 查看文件的ASCALL码
od -c hole
- 查看文件磁盘块大小
sudo tune2fs -l /dev/sda1
- 我们每次一次io读写文件,读写的基本单位是一个磁盘块,一个磁盘块的大小是4096个字节。所以缓存大小设置为磁盘块的大小
6. int dup(int oldfd);


- **是将oldfd的文件描述符表的指针复制给newfd,使oldfd和newfd都指向oldfd的文件描述符表的指针**
-
头文件:
<unistd.h> -
功能:复制一个文件描述符。
-
参数:
int oldfd:要复制的文件描述符。
-
返回值:成功时返回新的文件描述符;如果发生错误,则返回-1。
-
例子:
#include <unistd.h> #include <stdio.h>int main() {int fd = open("example.txt", O_RDWR);if (fd == -1) {perror("open");return 1;}int new_fd = dup(fd);if (new_fd == -1) {perror("dup");close(fd);return 1;}close(fd);close(new_fd);return 0; }
实现cat命令
#include"io.h"
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<fcntl.h>int main(int argc, char *argv[])
{int fd_in = STDIN_FILENO;int fd_out = STDOUT_FILENO;for(int i=1;i<argc;i++) // 这里是为了实现输入 cat file.txt 的情况{fd_in = open(argv[i],O_RDONLY);if(fd_in<0){perror("open error");continue;}copy(fd_in,fd_out);close(fd_in);}if(argc==1) // 这里实现的是只是输入 cat命令时的情况copy(fd_in,fd_out);return 0;
}
实现±重定向
mcat + file.txt // 将file.txt输出到屏幕中,这要求将file.txt以只读方式打开之后,将其文件描述符表的指针复制给标准输入
mcat - file.txt //将屏幕输入的内容输出到file.txt中,这要求以可读方式打开file.txt之后,将其文件描述符表指针复制给标准输出
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<fcntl.h>
#include<string.h>
#include"io.h"
/*bin/mcat + file +为输入从定向bin/mcat - file - 为输出重定向
*/int main(int argc,char *argv[])
{int fd_in,fd_out;int flag = 0;for(int i =1;i<argc;i++){if(!strcmp("+",argv[i])){fd_in = open(argv[++i],O_RDONLY);if(fd_in<0){perror("poen error");exit(1);}// 将标准输入重定向到文件if(dup2(fd_in,STDIN_FILENO)!=STDIN_FILENO){perror("dup2 error");exit(1);}close(fd_in);}else if(!strcmp("-",argv[i])){// 将文件的内容不是输出到屏幕而是输出到一个文件中fd_out = open(argv[++i],O_WRONLY|O_CREAT|O_TRUNC,0777);if(fd_out<0){perror("open error");exit(1);}if(dup2(fd_out,STDOUT_FILENO)!=STDOUT_FILENO){perror("dup2 error");exit(1);}close(fd_out);}else{flag = 1;fd_in = open(argv[i],O_RDONLY);if(fd_in<0){perror("open error");exit(1);}if(dup2(fd_in,STDIN_FILENO)){perror("dup2 error");exit(1);}copy(STDIN_FILENO,STDOUT_FILENO);close(fd_in);}}if(!flag)copy(STDIN_FILENO,STDOUT_FILENO);return 0;
}
文件描述符的复制
7. int dup2(int oldfd, int newfd);
-
头文件:
<unistd.h> -
功能:复制一个文件描述符,并将其绑定到另一个文件描述符。
-
参数:
int oldfd:要复制的文件描述符。int newfd:新的文件描述符。
-
返回值:成功时返回新的文件描述符;如果发生错误,则返回-1。
-
例子:
#include <unistd.h> #include <stdio.h>int main() {int fd = open("example.txt", O_RDWR);if (fd == -1) {perror("open");return 1;}int new_fd = dup2(fd, 3); // 将fd复制到文件描述符3if (new_fd == -1) {perror("dup2");close(fd);return 1;}close(fd);close(new_fd);return 0; }
文件操作的内核数据结构


int fcntl(int fd, int cmd, … /* arg */ );


fcntl 函数是 Unix 和类 Unix 操作系统中用于文件描述符控制的多功能函数。它可以执行多种与文件描述符相关的操作,如复制文件描述符、获取和设置文件状态标志、获取和设置文件锁等。
#include <fcntl.h>int fcntl(int fd, int cmd, ... /* arg */ );
-
fd:文件描述符,表示要操作的文件或 I/O 对象。 -
cmd:命令,指定要执行的操作。常见的命令包括:F_DUPFD:复制文件描述符。F_GETFD:获取文件描述符的标志。F_SETFD:设置文件描述符的标志。F_GETFL:获取文件状态标志。F_SETFL:设置文件状态标志。F_GETLK:获取文件锁。F_SETLK:设置文件锁。F_SETLKW:设置文件锁,等待锁释放。
-
arg:根据cmd的不同,第三个参数可能是整数、指向struct flock的指针或其他类型的参数。 -
- 复制文件描述符
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>int main() {int old_fd = 0; // 标准输入文件描述符int new_fd;// 复制文件描述符new_fd = fcntl(old_fd, F_DUPFD, 100); // 从100开始寻找最小的未使用的文件描述符if (new_fd == -1) {perror("fcntl F_DUPFD");return 1;}printf("Old FD: %d, New FD: %d\n", old_fd, new_fd);// 关闭新旧文件描述符close(old_fd);close(new_fd);return 0;
}
-
- 获取和设置文件描述符标志
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>int main() {int fd = Ⅰ; // 标准输入文件描述符int flags;// 获取文件描述符标志flags = fcntl(fd, F_GETFD);if (flags == -1) {perror("fcntl F_GETFD");return 1;}printf("Current flags: %d\n", flags);// 设置文件描述符标志if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) == -1) {perror("fcntl F_SETFD");return 1;}// 再次获取文件描述符标志flags = fcntl(fd, F_GETFD);if (flags == -1) {perror("fcntl F_GETFD");return 1;}printf("New flags: %d\n", flags);return 0;
}
-
- 获取和设置文件状态标志
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>int main() {int fd = Ⅰ; // 标准输入文件描述符int flags;// 获取文件状态标志flags = fcntl(fd, F_GETFL);if (flags == -1) {perror("fcntl F_GETFL");return 1;}printf("Current file status flags: %d\n", flags);// 设置文件状态标志if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1) {perror("fcntl F_SETFL");return 1;}// 再次获取文件状态标志flags = fcntl(fd, F_GETFL);if (flags == -1) {perror("fcntl F_GETFL");return 1;}printf("New file status flags: %d\n", flags);return 0;
}
-
- 文件锁
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/file.h>int main() {int fd;struct flock lock;// 打开文件fd = open("example.txt", O_RDWR | O_CREAT, 06½);if (fd == -1) {perror("open");return 1;}// 初始化文件锁结构lock.l_type = F_WRLCK; // 写锁lock.l_whence = SEEK_SET;lock.l_start = 0;lock.l_len = 0; // 整个文件lock.l_pid = getpid();// 设置文件锁if (fcntl(fd, F_SETLK, &lock) == -1) {perror("fcntl F_SETLK");close(fd);return 1;}// 释放文件锁lock.l_type = F_UNLCK;if (fcntl(fd, F_SETLK, &lock) == -1) {perror("fcntl F_SETLK");close(fd);return 1;}// 关闭文件close(fd);return 0;
}
总结
fcntl 函数是一个非常强大的工具,可以用于多种文件描述符相关的操作。以下是一些常见的操作:
- 复制文件描述符:
F_DUPFD - 获取和设置文件描述符标志:
F_GETFD和F_SETFD - 获取和设置文件状态标志:
F_GETFL和F_SETFL - 文件锁:
F_GETLK、F_SETLK和F_SETLKW
设置文件标准标志
void set_fl(int fd,int flag)
{int val = fcntl(fd,F_GETFL);// 获取原来的文件状态n标志val|=flag; // 增加新的文件状态标志if(fcntl(fd,F_SETFL,val)<0)fprintf(stderr,"fcntl error %s\n",strerror(errno));
}void clr_fl(int fd,int flag)
{int val = fcntl(fd,F_GETFL);// 清除指定的文件状态标志val&=~flag;if(fcntl(fd,F_SETFL,val)<0)fprintf(stderr,"fcntl error %s",strerror(errno));}
文件描述符标志和文件状态标志的区别
在 fcntl 函数中,文件描述符标志(File Descriptor Flags)和文件状态标志(File Status Flags)是两种不同类型的状态标志,它们各自有不同的用途和意义。
文件描述符标志(File Descriptor Flags)
文件描述符标志是与特定文件描述符相关联的标志,而不是与文件本身相关联的标志。这些标志通常影响文件描述符的行为,特别是在进程执行 exec 系列函数时。
常见的文件描述符标志
FD_CLOEXEC:这是一个非常重要的标志。当设置此标志时,文件描述符将在执行exec系列函数时自动关闭。如果没有设置此标志,文件描述符将保持打开状态。
设置和获取文件描述符标志
-
获取文件描述符标志:
int flags = fcntl(fd, F_GETFD); if (flags == -1) {perror("fcntl F_GETFD");return 1; } -
设置文件描述符标志:
if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) == -1) {perror("fcntl F_SETFD");return 1; }
文件状态标志(File Status Flags)
文件状态标志是与文件本身相关联的标志,它们影响文件的打开方式和 I/O 操作的行为。这些标志通常在打开文件时通过 open 函数的 flags 参数设置,也可以在文件打开后通过 fcntl 函数修改。
常见的文件状态标志
O_RDONLY:只读模式。O_WRONLY:只写模式。O_RDWR:读写模式。O_APPEND:每次写操作都追加到文件末尾。O_NONBLOCK:非阻塞模式。O_SYNC:同步写操作,确保数据立即写入磁盘。O_CREAT:如果文件不存在,则创建文件。O_TRUNC:如果文件已存在且为只写或读写模式,则截断文件长度为0。O_EXCL:与O_CREAT一起使用,如果文件已存在,则打开失败。
设置和获取文件状态标志
-
获取文件状态标志:
int flags = fcntl(fd, F_GETFL); if (flags == -1) {perror("fcntl F_GETFL");return 1; } -
设置文件状态标志:
if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1) {perror("fcntl F_SETFL");return 1; }
主要区别
-
作用对象:
- 文件描述符标志:作用于特定的文件描述符,影响文件描述符的行为。
- 文件状态标志:作用于文件本身,影响文件的打开方式和 I/O 操作的行为。
-
使用场景:
- 文件描述符标志:主要用于控制文件描述符在
exec系列函数执行时的行为。 - 文件状态标志:主要用于控制文件的打开方式和 I/O 操作的行为。
- 文件描述符标志:主要用于控制文件描述符在
-
标志位:
- 文件描述符标志:主要标志是
FD_CLOEXEC。 - 文件状态标志:包括
O_RDONLY、O_WRONLY、O_RDWR、O_APPEND、O_NONBLOCK、O_SYNC等。
- 文件描述符标志:主要标志是
示例
以下是一个示例,展示了如何分别获取和设置文件描述符标志和文件状态标志:
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>int main() {int fd;int fd_flags, fl_flags;// 打开文件fd = open("example.txt", O_RDWR | O_CREAT, 0644);if (fd == -1) {perror("open");return 1;}// 获取文件描述符标志fd_flags = fcntl(fd, F_GETFD);if (fd_flags == -1) {perror("fcntl F_GETFD");close(fd);return 1;}printf("Current FD flags: %d\n", fd_flags);// 设置文件描述符标志if (fcntl(fd, F_SETFD, fd_flags | FD_CLOEXEC) == -1) {perror("fcntl F_SETFD");close(fd);return 1;}printf("New FD flags: %d\n", fcntl(fd, F_GETFD));// 获取文件状态标志fl_flags = fcntl(fd, F_GETFL);if (fl_flags == -1) {perror("fcntl F_GETFL");close(fd);return 1;}printf("Current file status flags: %d\n", fl_flags);// 设置文件状态标志if (fcntl(fd, F_SETFL, fl_flags | O_NONBLOCK) == -1) {perror("fcntl F_SETFL");close(fd);return 1;}printf("New file status flags: %d\n", fcntl(fd, F_GETFL));// 关闭文件close(fd);return 0;
}
总结
- 文件描述符标志:与特定文件描述符相关联,影响文件描述符的行为,特别是
exec时的行为。 - 文件状态标志:与文件本身相关联,影响文件的打开方式和 I/O 操作的行为。
希望这些信息对你有帮助!如果你有任何其他问题或需要进一步的解释,请告诉我。
文件的原子操作
I/O处理模型

非阻塞IO

-
设置阻塞方式,睡眠之后会等待输入
#include<stdio.h> #include<fcntl.h> #include<unistd.h> #include<string.h> #include<stdlib.h>int main() {char buffer[4096] = {'\0'};ssize_t size = 0;sleep(5);size = read(STDIN_FILENO,buffer,sizeof(buffer)); // 默认是阻塞的if(size<0){perror("read error");exit(1);}else if(size==0){printf("read finished!\n");}else{if(write(STDOUT_FILENO,buffer,size)!=size)perror("write error");}return 0; } -
当设置为阻塞方式时,没有输入内容会报错
int main() {char buffer[4096] = {'\0'};ssize_t size = 0;set_fl(STDIN_FILENO,O_NONBLOCK);sleep(5);size = read(STDIN_FILENO,buffer,sizeof(buffer));// 设置非阻塞if(size<0){perror("read error");exit(1);}else if(size==0){printf("read finished!\n");}else{if(write(STDOUT_FILENO,buffer,size)!=size)perror("write error");}return 0; }
文件锁机制
存储映射
--------------------
文件操作函数
文件共享机制
相关文章:
Linux系统程序设计--2. 文件I/O
文件I/O 标准C的I/O FILE结构体 下面只列出了5个成员 可以观察到,有些函数没有FILE类型的结构体指针例如printf主要是一些标准输出,因为其内部用到了stdin,stdout,stderr查找文件所在的位置:find \ -name stat.h查找头文件所…...
右值引用——C++11新特性(一)
目录 一、右值引用与移动语义 1.左值引用与右值引用 2.移动构造和移动赋值 二、引用折叠 三、完美转发 一、右值引用与移动语义 1.左值引用与右值引用 左值:可以取到地址的值,比如一些变量名,指针等。右值:不能取到地址的值…...
JavaScript 观察者设计模式
观察者模式:观察者模式(Observer mode)指的是函数自动观察数据对象,一旦对象有变化,函数就会自动执行。而js中最常见的观察者模式就是事件触发机制。 ES5/ES6实现观察者模式(自定义事件) - 简书 先搭架子 要有一个对象ÿ…...
鸿蒙进阶篇-网格布局 Grid/GridItem(二)
hello大家好,这里是鸿蒙开天组,今天让我们来继续学习鸿蒙进阶篇-网格布局 Grid/GridItem,上一篇博文我们已经学习了固定行列、合并行列和设置滚动,这一篇我们将继续学习Grid的用法,实现翻页滚动、自定义滚动条样式&…...
数据仓库之 Atlas 血缘分析:揭示数据流奥秘
Atlas血缘分析在数据仓库中的实战案例 在数据仓库领域,数据血缘分析是一个重要的环节。血缘分析通过确定数据源之间的关系,以及数据在处理过程中的变化,帮助我们更好地理解数据生成的过程,提高数据的可靠性和准确性。在这篇文章中…...
AndroidStudio-滚动视图ScrollView
滚动视图 滚动视图有两种: 1.ScrollView,它是垂直方向的滚动视图;垂直方向滚动时,layout_width属性值设置为match_parent,layout_height属性值设置为wrap_content。 例如: (1)XML文件中: <?xml ve…...
嵌入式硬件实战基础篇(一)-STM32+DAC0832 可调信号发生器-产生方波-三角波-正弦波
引言:本内容主要用作于学习巩固嵌入式硬件内容知识,用于想提升下述能力,针对学习STM32与DAC0832产生波形以及波形转换,对于硬件的降压和对于前面硬件篇的实际运用,针对仿真的使用,具体如下: 设…...
ElasticSearch的Python Client测试
一、Python环境准备 1、下载Python安装包并安装 https://www.python.org/ftp/python/3.13.0/python-3.13.0-amd64.exe 2、安装 SDK 参考ES官方文档: https://www.elastic.co/guide/en/elasticsearch/client/index.html python -m pip install elasticsearch一、Client 代…...
【eNSP】企业网络架构链路聚合、数据抓包、远程连接访问实验(二)
一、实验目的 网络分段与VLAN划分: 通过实验了解如何将一个大网络划分为多个小的子网(VLAN),以提高网络性能和安全性。 VLAN间路由: 学习如何配置VLAN间的路由,使不同VLAN之间能够通信。 网络设备配置&am…...
独立站 API 接口的性能优化策略
一、缓存策略* 数据缓存机制 内存缓存:利用内存缓存系统(如 Redis 或 Memcached)来存储频繁访问的数据。例如,对于商品信息 API,如果某些热门商品的详情(如价格、库存、基本描述等)被大量请求…...
不一样的CSS(一)
目录 前言: 一、规则图形 1.介绍: 2.正方形与长方形(实心与空心) 2.1正方形: 2.2长方形 3.圆形与椭圆形(空心与实心) 3.1圆形与椭圆形 4.不同方向的三角形 4.1原理 4.2边框属性 5.四…...
题目:Wangzyy的卡牌游戏
登录 - XYOJ 思路: 使用动态规划,设dp[n]表示当前数字之和模三等于0的组合数。 状态转移方程:因为是模三,所以和的可能就只有0、1、2。等号右边的f和dp都表示当前一轮模三等于k的组合数。以第一行为例:等号右边表示 j转…...
国外云服务器高防多少钱一年?
国外云服务器高防多少钱一年?入门级高防云主机:这类主机通常具有较低的防御峰值,如30G或60G,价格相对较低。例如,30G峰值防御的高防云主机年费可能在2490元左右,而60G峰值防御的则可能在5044元左右。中等防…...
架构篇(04理解架构的演进)
目录 学习前言 一、架构演进 1. 初始阶段的网站架构 2. 应用服务和数据服务分离 3. 使用缓存改善网站性能 4. 使用应用服务器集群改善网站的并发处理能力 5. 数据库读写分离 6. 使用反向代理和CDN加上网站相应 7. 使用分布式文件系统和分布式数据库系统 8. 使用NoSQL和…...
【363】基于springboot的高校竞赛管理系统
摘 要 如今社会上各行各业,都喜欢用自己行业的专属软件工作,互联网发展到这个时候,人们已经发现离不开了互联网。新技术的产生,往往能解决一些老技术的弊端问题。因为传统高校竞赛管理系统信息管理难度大,容错率低&am…...
Spring Boot 监视器
一、Spring Boot 监视器概述 (一)什么是 Spring Boot 监视器 定义与作用 Spring Boot 监视器(Spring Boot Actuator)是一个用于监控和管理 Spring Boot 应用程序的工具集。它提供了一系列的端点,可以获取应用程序的运…...
Javascript如何获取指定网页中的内容?
这两天有一个需求,就是通过JS去获取网页的内容,当然,除了今天我要分享的这个方法以外,其实通过Ajax的Get方法也是可以实现这个功能的,但是Ajax就比较麻烦一些了,如果只是单纯的想要获取一下纯内容ÿ…...
第2章2.3立项【硬件产品立项的核心内容】
硬件产品立项的核心内容 2.3 硬件产品立项的核心内容2.3.1 第一步:市场趋势判断2.3.2 第二步:竞争对手分析1.竞争对手识别2.根据竞争对手分析制定策略 2.3.3 第三步:客户分析2.3.4 第四步:产品定义2.3.5 第五步:开发执…...
区块链:Raft协议
Raft 协议是一种分布式共识机制,这种机制适用于网络中存在一定数量的故障节点,但不考虑“恶意”节点的情况,所以更适合作为私有链和联盟链的共识算法。 在此协议中,每个节点有三种状态: 候选者 ,可以被选…...
【C语言】位运算
我们在上学计算机的第一节课,就应该见过这些常见的运算符。然而,你可能有印象,但记不住众多操作符当中的位运算符,以及它们的作用和使用场景,我们的大脑会选择性地遗忘它认为没用的信息,存储下那些“有实际…...
设计模式和设计原则回顾
设计模式和设计原则回顾 23种设计模式是设计原则的完美体现,设计原则设计原则是设计模式的理论基石, 设计模式 在经典的设计模式分类中(如《设计模式:可复用面向对象软件的基础》一书中),总共有23种设计模式,分为三大类: 一、创建型模式(5种) 1. 单例模式(Sing…...
TDengine 快速体验(Docker 镜像方式)
简介 TDengine 可以通过安装包、Docker 镜像 及云服务快速体验 TDengine 的功能,本节首先介绍如何通过 Docker 快速体验 TDengine,然后介绍如何在 Docker 环境下体验 TDengine 的写入和查询功能。如果你不熟悉 Docker,请使用 安装包的方式快…...
Debian系统简介
目录 Debian系统介绍 Debian版本介绍 Debian软件源介绍 软件包管理工具dpkg dpkg核心指令详解 安装软件包 卸载软件包 查询软件包状态 验证软件包完整性 手动处理依赖关系 dpkg vs apt Debian系统介绍 Debian 和 Ubuntu 都是基于 Debian内核 的 Linux 发行版ÿ…...
Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility
Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility 1. 实验室环境1.1 实验室环境1.2 小测试 2. The Endor System2.1 部署应用2.2 检查现有策略 3. Cilium 策略实体3.1 创建 allow-all 网络策略3.2 在 Hubble CLI 中验证网络策略源3.3 …...
【论文笔记】若干矿井粉尘检测算法概述
总的来说,传统机器学习、传统机器学习与深度学习的结合、LSTM等算法所需要的数据集来源于矿井传感器测量的粉尘浓度,通过建立回归模型来预测未来矿井的粉尘浓度。传统机器学习算法性能易受数据中极端值的影响。YOLO等计算机视觉算法所需要的数据集来源于…...
WordPress插件:AI多语言写作与智能配图、免费AI模型、SEO文章生成
厌倦手动写WordPress文章?AI自动生成,效率提升10倍! 支持多语言、自动配图、定时发布,让内容创作更轻松! AI内容生成 → 不想每天写文章?AI一键生成高质量内容!多语言支持 → 跨境电商必备&am…...
【HTML-16】深入理解HTML中的块元素与行内元素
HTML元素根据其显示特性可以分为两大类:块元素(Block-level Elements)和行内元素(Inline Elements)。理解这两者的区别对于构建良好的网页布局至关重要。本文将全面解析这两种元素的特性、区别以及实际应用场景。 1. 块元素(Block-level Elements) 1.1 基本特性 …...
Spring AI 入门:Java 开发者的生成式 AI 实践之路
一、Spring AI 简介 在人工智能技术快速迭代的今天,Spring AI 作为 Spring 生态系统的新生力量,正在成为 Java 开发者拥抱生成式 AI 的最佳选择。该框架通过模块化设计实现了与主流 AI 服务(如 OpenAI、Anthropic)的无缝对接&…...
关于 WASM:1. WASM 基础原理
一、WASM 简介 1.1 WebAssembly 是什么? WebAssembly(WASM) 是一种能在现代浏览器中高效运行的二进制指令格式,它不是传统的编程语言,而是一种 低级字节码格式,可由高级语言(如 C、C、Rust&am…...
省略号和可变参数模板
本文主要介绍如何展开可变参数的参数包 1.C语言的va_list展开可变参数 #include <iostream> #include <cstdarg>void printNumbers(int count, ...) {// 声明va_list类型的变量va_list args;// 使用va_start将可变参数写入变量argsva_start(args, count);for (in…...
