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
:允许手动设置缓冲方式和缓冲区大小。
特殊情况
- 标准错误
stderr
stderr
默认是无缓冲的,这样可以确保错误信息立即显示,不会因为缓冲而延迟。- 使用
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语言】位运算
我们在上学计算机的第一节课,就应该见过这些常见的运算符。然而,你可能有印象,但记不住众多操作符当中的位运算符,以及它们的作用和使用场景,我们的大脑会选择性地遗忘它认为没用的信息,存储下那些“有实际…...
计算机体系结构之多级缓存、缓存miss及缓存hit(二)
前面章节《计算机体系结构之缓存机制原理及其应用(一)》讲了关于缓存机制的原理及其应用,其中提出了多级缓存、缓存miss以及缓存hit的疑问。故,本章将进行展开讲解, 多级缓存、缓存miss以及缓存hit存在的意义是为了保持…...
【R78/G15 开发板测评】串口打印 DHT11 温湿度传感器、DS18B20 温度传感器数据,LabVIEW 上位机绘制演化曲线
【R78/G15 开发板测评】串口打印 DHT11 温湿度传感器、DS18B20 温度传感器数据,LabVIEW 上位机绘制演化曲线 主要介绍了 R78/G15 开发板基于 Arduino IDE 环境串口打印温湿度传感器 DHT11 和温度传感器 DS18B20 传感器的数据,并通过LabVIEW上位机绘制演…...
Oracle Fetch子句
FETCH 子句在 Oracle 中可以用来限制查询返回的行数 Oracle FETCH 子句语法 以下说明了行限制子句的语法: [ OFFSET offset ROWS]FETCH NEXT [ row_count | percent PERCENT ] ROWS [ ONLY | WITH TIES ]OFFSET 子句 OFFSET 子句指定在行限制开始之前要跳过行…...
Linux应用——线程池
1. 线程池要求 我们创建线程池的目的本质上是用空间换取时间,而我们选择于 C 的类内包装原生线程库的形式来创建,其具体实行逻辑如图 可以看到,整个线程池其实就是一个大型的 CP 模型,接下来我们来完成它 2. 整体模板 #pragma …...
95.【C语言】数据结构之双向链表的头插,头删,查找,中间插入,中间删除和销毁函数
目录 1.双向链表的头插 方法一 方法二 2.双向链表的头删 3.双向链表的销毁 4.双向链表的某个节点的数据查找 5.双向链表的中间插入 5.双向链表的中间删除 6.对比顺序表和链表 承接94.【C语言】数据结构之双向链表的初始化,尾插,打印和尾删文章 1.双向链表的头插 方法…...
leetcode82:删除排序链表中的重复节点||
给定一个已排序的链表的头 head , 删除原始链表中所有重复数字的节点,只留下不同的数字 。返回 已排序的链表 。 示例 1: 输入:head [1,2,3,3,4,4,5] 输出:[1,2,5]示例 2: 输入:head [1,1,1,2…...
【C#】使用.net9在C#中向现有对象动态添加属性
在 C# 中向现有对象动态添加属性并不像在 Python 或 JavaScript 中那样容易,因为 C# 是一种强类型语言。 但是,我们可以通过使用一些技术和库来实现这一点,例如扩展方法、字典等。本文将详细介绍如何在 C# 中实现这一点。ExpandoObject 方法 …...
Linux进程信号(信号的产生)
目录 什么是信号? 信号的产生 信号产生方式1:键盘 前台进程 后台进程 查看信号 signal系统调用 案例 理解进程记录信号 软件层面 硬件层面 信号产生方式2:指令 信号产生方式3:系统调用 kill系统调用 案例 其他产生信号的函数调用 1.rais…...
97_api_intro_imagerecognition_pdf2word
通用 PDF OCR 到 Word API 数据接口 文件处理,OCR,PDF 高可用图像识别引擎,基于机器学习,超精准识别率。 1. 产品功能 通用识别接口;支持中英文等多语言字符混合识别;formdata 格式 PDF 文件流传参…...
【算法】【优选算法】二分查找算法(上)
目录 一、二分查找简介1.1 朴素二分模板1.2 查找区间左端点模版1.3 查找区间右端点模版 二、leetcode 704.⼆分查找2.1 二分查找2.2 暴力枚举 三、Leetcode 34.在排序数组中查找元素的第⼀个和最后⼀个位置3.1 二分查找3.2 暴力枚举 四、35.搜索插⼊位置4.1 二分查找4.2 暴力枚…...
宜昌做网站的/极速一区二区三区精品
DHCP基础部分DHCP全称 Dynamic Host Configuration Protocol (动态主机配置协议)。提供主机 IP 地址的动态租用配置、并将其他配置参数分配给合法网络客户的 TCP/IP 服务协议。DHCP 提供既安全、可靠,又简便的 TCP/IP 网络配置,可…...
网站备案安全承诺书/爱站网关键词长尾挖掘工具
设向量a和向量b 则a•b|a||b|cos,|a|和|b|分别为两向量的模 cos即为两向量的余弦值,所以cosa•b/|a||b| 距离和相似性度量: http://blog.sina.com.cn/s/blog_6045a9da01011nk7.html 转载于:https://www.cnblogs.com/lsai/p/3715948.html...
邯郸建设网站制作/新手怎么学网络运营
下载workerman的linux包。并新建start.php文件,内容如下: <?php use Workerman\Worker; require_once Autoloader.php;$global_uid 0;// 当客户端连上来时分配uid,并保存连接,并通知所有客户端 function handle_connection(…...
南昌网站建设公司机构/北京做网站的公司排行
1、Timestamp(long)转成日期 Timestamp timestamp new Timestamp(System.currentTimeMillis()); LocalDateTime localDateTime timestamp.toLocalDateTime(); //之后就可以通过java8 新API操作时间了 localDateTime.toLocalDate(); Date da…...
广东建网站的公司/seo有哪些网站
问题描述: 三格布局,左右宽度固定为200px,中间宽度随屏幕变化而变化 代码如下: 1 <!DOCTYPE html>2 <html lang"en">3 <head>4 <meta charset"UTF-8">5 <title>Document</titl…...
朋友让帮忙做网站/网站怎么做优化排名
一、引入jar包此处以marvern项目为例 pom.xml文件中引入以下内容: <!--FastDFS --><dependency><groupId>org.csource.fastdfs</groupId><artifactId>fastdfs_client</artifactId><version>1.24</version></dep…...