邯郸个人做网站上海seo公司排名
目录
- 1.文件IO
- 1.1 文件IO分类
- 1.2 查看系统调用IO用法
- 2. open 函数
- 3. write 函数
- 4. read 函数
- 5 dup函数
1.文件IO
1.1 文件IO分类
在Linux系统中,一切都是“文件”:普通文件、驱动程序、网络通信等。所有的操作都是通过文件IO来操作的。
在Linux操作文件时,有2套函数
- 标准IO: fopen/fread/fwrite/fseek/fflush/fclose
- 系统调用IO: open/read/write/lseek/fsync/close
这2种IO的区别
标准IO是在系统调用IO的基础上封装出的一套函数,标准IO引入了用户buffer,其底层还是系统调用IO。
用户buffer的作用:系统调用IO每读一次都进入一次内核,效率低。在使用fread时,会一次读取出很多字节,存入到用户buffer中,后续的read就从用户buffer中读。写入时也是先写入到用户buffer中,当达到一定条件后,一次性写入到内核中。使用标准IO可以提高效率。
1.2 查看系统调用IO用法
man手册可以查看命令的用法,还可以查看函数的详细介绍。
输入 man man 命令,可以看到包含9大类手册:
MAN(1) Manual pager utils MAN(1)NAMEman - an interface to the on-line reference manualsSYNOPSISman [-C file] [-d] [-D] [--warnings[=warnings]] [-R encoding] [-L locale] [-m system[,...]] [-M path] [-S list] [-e extension] [-i|-I][--regex|--wildcard] [--names-only] [-a] [-u] [--no-subpages] [-P pager] [-r prompt] [-7] [-E encoding] [--no-hyphenation] [--no-justification][-p string] [-t] [-T[device]] [-H[browser]] [-X[dpi]] [-Z] [[section] page[.section] ...] ...man -k [apropos options] regexp ...man -K [-w|-W] [-S list] [-i|-I] [--regex] [section] term ...man -f [whatis options] page ...man -l [-C file] [-d] [-D] [--warnings[=warnings]] [-R encoding] [-L locale] [-P pager] [-r prompt] [-7] [-E encoding] [-p string] [-t][-T[device]] [-H[browser]] [-X[dpi]] [-Z] file ...man -w|-W [-C file] [-d] [-D] page ...man -c [-C file] [-d] [-D] page ...man [-?V]DESCRIPTIONman is the system's manual pager. Each page argument given to man is normally the name of a program, utility or function. The manual page asso‐ciated with each of these arguments is then found and displayed. A section, if provided, will direct man to look only in that section of themanual. The default action is to search in all of the available sections following a pre-defined order ("1 n l 8 3 2 3posix 3pm 3perl 3am 5 4 96 7" by default, unless overridden by the SECTION directive in /etc/manpath.config), and to show only the first page found, even if page existsin several sections.The table below shows the section numbers of the manual followed by the types of pages they contain.1 Executable programs or shell commands // 命令2 System calls (functions provided by the kernel) // 系统调用3 Library calls (functions within program libraries) // 函数库调用4 Special files (usually found in /dev) // 特殊文件5 File formats and conventions eg /etc/passwd // 文件格式和约定6 Games // 游戏7 Miscellaneous (including macro packages and conventions), e.g. man(7), groff(7) // 杂项8 System administration commands (usually only for root) // 系统管理命令9 Kernel routines [Non standard] // 内核例程A manual page consists of several sections.
查看系统调用IO
man 2 open输出内容:
OPEN(2) Linux Programmer's Manual OPEN(2)NAMEopen, openat, creat - open and possibly create a fileSYNOPSIS#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>int open(const char *pathname, int flags);int open(const char *pathname, int flags, mode_t mode);int creat(const char *pathname, mode_t mode);int openat(int dirfd, const char *pathname, int flags);int openat(int dirfd, const char *pathname, int flags, mode_t mode);Feature Test Macro Requirements for glibc (see feature_test_macros(7)):openat():Since glibc 2.10:_POSIX_C_SOURCE >= 200809LBefore glibc 2.10:_ATFILE_SOURCEDESCRIPTIONThe open() system call opens the file specified by pathname. If the specified file does not exist, it may optionally (if O_CREAT is specified inflags) be created by open().
......
2. open 函数
1)open
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>/*./open 1.txtargc = 2argv[0] = "./open"argv[1] = "1.txt"
*/
int main(int argc, char **argv)
{int fd;if(argc != 2){printf("Usage: %s <file>\n", argv[0]);return -1;}else{printf("fd: %d\n", fd);}fd = open(argv[1], O_RDWR);if(fd < 0){printf("can not open file %s\n", argv[1]);printf("errno = %d\n", errno);printf("err: %s\n", strerror(errno));perror("open");}while(1){sleep(10);}close(fd);return 0;
}
2)create
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>/*./create 1.txtargc = 2argv[0] = "./create"argv[1] = "1.txt"
*/
int main(int argc, char **argv)
{int fd;if(argc != 2){printf("Usage: %s <file>\n", argv[0]);return -1;}else{printf("fd: %d\n", fd);}// O_TRUNC: 截断,清空// 0666 : 文件权限,8进制,rwx ,6即110 可读可写// -rw-rw-r-- : owner-group-other// 注意:无法改变other用户的w权限fd = open(argv[1], O_RDWR | O_CREAT | O_TRUNC, 0666);if(fd < 0){printf("can not open file %s\n", argv[1]);perror("open");}while(1){sleep(10);}close(fd);return 0;
}
注意:用open创建文件时设置mode权限,最终得到的文件权限为 mode & ~umask。umask命令可以查看当前用户不能获取的权限。
3. write 函数
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>/*./write 1.txt str1 str2argc = 3 // 至少3个参数argv[0] = "./write"argv[1] = "1.txt"
*/
int main(int argc, char **argv)
{int fd,i,len;if(argc < 3){printf("Usage: %s <file> <str1> <str2>\n", argv[0]);return -1;}else{printf("fd: %d\n", fd);}fd = open(argv[1], O_RDWR | O_CREAT, 0666);if(fd < 0){printf("can not open file %s\n", argv[1]);perror("open");}for(i = 2; i < argc; i++){len = write(fd, argv[i], strlen(argv[i]));if(len != strlen(argv[i])){perror("write");break;}write(fd, "\r\n", 2);}close(fd);return 0;
可以使用lseek移动写入位置的指针,注意再写入的内容会将原位置的内容覆盖。
4. read 函数
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>/*./read 1.txtargc = 2argv[0] = "./read"argv[1] = "1.txt"
*/
int main(int argc, char **argv)
{int fd,i,len;unsigned int buf[100];if(argc != 2){printf("Usage: %s <file>\n", argv[0]);return -1;}else{printf("fd: %d\n", fd);}fd = open(argv[1], O_RDONLY);if(fd < 0){printf("can not open file %s\n", argv[1]);perror("open");}while(1){len = read(fd, buf, sizeof(buf)-1);if(len < 0){perror("read");close(fd);return -1;}else if(len == 0) // 读到文件尾部{break;}else{buf[len-1] = '\0';printf("%s",buf);}}close(fd);return 0;
}
5 dup函数
作用:复制文件描述符,即两个文件句柄指向同一个文件描述符,这两个文件句柄共享文件偏移地址
- dup : int dup(int oldfd);
- dup2:int dup2(int oldfd,int newfd);
- dup3:int dup3(int oldfd,int newfd,int flags);
- oldfd:被复制的文件句柄
- newfd:复制得到的文件句柄
注意:
- dup函数返回的文件句柄是 未使用的最小文件句柄。
- dup2 可以指定复制得到的文件句柄为newfd。
- dup3 跟dup2 类似,flags参数要么是0,要么是0_CLOEXEC
To Be Continue …