熟悉linux系统的同学都知道,所有的设备在linux下都被当作文件来处理,因此了解文件的I/O操作是十分重要的。
1/具体来说,有以下几种文件类型(控制台ls -l命令的第一列即为文件类型):
符号 | 类型 | 符号 | 类型 |
s | 套接字文件 | d | 目录文件 |
l | 链接文件 | b | 块设备文件 |
c | 字符设备文件 | p | 管道文件 |
- | 普通文件 |
另外,有几个特殊的文件,标准输入,标准输出,标准出错
类型 | 文件描述符 | 说明 |
标准输入 | 0 | 它是命令的输入,默认是键盘,也可以是文件或其他命令的输出。使用'<'或'0<'符号进行重定向。 |
标准输入 | 1 | 它是命令的输出,默认是屏幕,也可以是其他文件。使用'>'或'1>'符号进行重定向。 |
标准出错 | 2 | 它是命令出错信息的输出,默认是屏幕,也可以是其他文件。使用'2>'符号进行重定向。 |
2/LINUX通过文件权限,来管理文件的读/写/执(wrx)行权限。
3/文件操作函数总结:
在开始列写具体函数之前,我们首先列出文件I/O中的常用参数表:
flag参数(头文件:fcntl.h)
取值 | 含义 |
O_RDONLY | 以只读方式打开文件 |
O_WRONLY | 以只写方式打开文件 |
O_RDWR | 以读写方式打开文件 |
O_CREAT | 若要打开的文件不存在,则创建一个。权限在mode参数中说明 |
O_EXCL | 与O_CREAT配合使用以验证一个文件是否存在 |
O_TRUNC | 如果文件存在,且以只读或只写方式打开,则将其长度截短为0 |
O_NOCTTY | 如果文件描述符指向终端设备,则不将此设备分配为此进程控制终端 |
O_APPEND | 写入时追加到文件结尾 |
O_NONBLOCK | 将后续的I/O操作设置为非阻塞方式 |
O_NONELAY | 功能不那么完善的O_NONBLOCK |
O_SYNC | 只有数据被写入外存或其他设备之后操作才返回 |
mode参数(头文件:fcntl.h)
取值 | 八进制 | 含义 |
S_ISUID | 04000 | 设置用户识别号 |
S_ISGID | 02000 | 设置组号 |
S_SVTX | 01000 | 粘贴位 |
S_IRUSR | 00400 | 文件所有者的读权限位 |
S_IWUSR | 00200 | 文件所有者的写权限位 |
S_IXUSR | 00100 | 文件所有者的执行权限位 |
S_IWGRP | 00040 | 该组用户的读权限位 |
S_IRGRP | 00020 | 该组用户的写权限位 |
S_IXGRP | 00010 | 该组用户的执行权限位 |
S_IROTH | 00004 | 其他组用户的读权限位 |
S_IWOTH | 00002 | 其他组用户的写权限位 |
S_IXOTH | 00001 | 其他组用户的执行权限位 |
S_IRWXU | 00600 | 文件所有者的读+写+执行权限 |
S_IRWXG | 00060 | 该组用户的读+写+执行权限 |
S_IRWXO | 00006 | 其他组用户的读+写+执行权限 |
whence参数(头文件:sys/types.h)
取值 | 含义 |
SEEK_SET | 将该文件的位移量设置为距文件开始处offset个字节处 |
SEEK_CUR | 将该文件的位移量设置为距当前位置offset个字节处。offset可正可负。 |
SEEK_END | 将该文件的位移量设置为距文件结尾处offset个字节处offset可正可负。 |
取值 | 相应操作 |
F_DUPFD | 复制一个现存文件描述符 |
F_GETFD | 获得文件描述符 |
F_SETFD | 设置文件描述符 |
F_GETFL | 获得文件状态标志 |
F_SETFL | 设置文件状态标志 |
F_GETOWN | 获得异步I/O权 |
F_SETOWN | 设置异步I/0权 |
F_GETLK | 获得记录锁 |
F_SETLK | 设置记录锁,不等待 |
F_SETLKW | 设置记录锁,必要时等待 |
#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);
两个函数在成功后都返回文件描述符,以用作后续操作,并且将该文件的引用计数器值加1;出错返回-1。mode参数可以直接使用八进制表示。
#include <fcntl.h> int creat(const char *pathname, mode_t mode);
成功则返回文件描述符,以用作后续操作;出错返回-1。创建成功后以只写方式打开文件。
#include<unistd.h> int close(int fd);
成功后该文件的引用计数器值减1,并且返回0;出错返回-1。
#include <unistd.h> off_t lseek(int fd, off_t offset, int whence);
成功后返回新的文件偏移量;出错返回-1。offset为正数时向后移动,为负数时向前移动。
#include <unistd.h> ssize_t read(int fd, void *buf, size_t nbytes);
成功后返回读取到的字节数;出错返回-1。
#include <unistd.h> ssize_t write(int fd, const void *buf, size_t nbytes);
成功后返回写入的字节数;出错返回-1。
#include <sys/types.h> #include <sys/stat.h> int chmod(const char *pathname, mode_t mode); int fchmod(int fd, mode_t mode);
#include <sys/types.h> #include <unistd.h> int chown(const char *pathname,uid_t owner,gid_t group); int fchown(int fd,uid_t owner,gid_t group); int lchown(const char *pathname,uid_t owner,gid_t group);
前两个函数功能一致,一个针对文件路径操作,一个针对文件描述符操作。成功后返回0;出错返回-1。
#include<stdio.h> int rename(const char *oldfname, const char *newfname);
#include<sys/types.h> #include<unistd.h> int truncate(const char * pathname,off_t len); int ftruncate(int fd,off_t len);
两个函数功能一致,一个针对文件路径操作,一个针对文件描述符操作。成功后返回0;出错返回-1。
#include <fcntl.h> #include <unistd.h> #include <sys/types.h> int fcntl(int fd, int cmd); int fcntl(int fd, int cmd, long arg); int fcntl(int fd, int cmd, struct flock *lock);
fcntl的返回值与命令有关。如果出错,所有命令都返回-1,如果成功则返回某个其他值。下列三个命令有特定返回值:F_DUPFD,F_GETFD,F_GETFL以及F_GETOWN。第一个返回新的文件描述符,第二个返回相应标志,最后一个返回一个正的进程ID或负的进程组ID。
#include <sys/stat.h> #include <sys/types.h> int stat(const char *pathname, struct stat *buf); int fstat(int fd, struct stat *buf); int lstat(const char *pathname, struct stat *buf);
前两个函数功能一致,一个针对文件路径操作,一个针对文件描述符操作。成功后返回0;出错返回-1。
#include <unistd.h> int dup (int fd); int dup2(int fd, int fd2);
两个函数复制文件描述符,成功后都返回新的文件描述符;出错返回-1。
#include <unistd.h> void sync(void); int fsync(int fd) ;
成功后返回0;出错返回-1。用于强制将系统缓存区内容写入文件。
#include <sys/stat.h> #include <sys/types.h> #include <unistd.h> #include <dirent.h> int mkdir(const char* pathname,mode_t mode); int rmdir(const char* pathname); DIR *opendir(const char *pathname); struct dirent *readdir(DIR *dp); int closedir(DIR *dp);
成功后返回0;出错返回-1。
#include <unistd.h> int chdir(const char *path ); int fchdir(int fd); char *getcwd(char *buf, size_t size);
前两个函数功能一致,一个针对文件路径操作,一个针对文件描述符操作。成功后返回0;出错返回-1。
#include <unistd.h> #include <stdio.h> int link(const char *pathname1, const char *pathname2); int unlink(const char *pathname); int remove(const char *pathname); int symlink(const char *actualpath, const char *sympath); int readlink(const char *pathname, char *buf, int bufsize);
前四函数成功后返回0;出错返回-1。readlink函数成功后返回读取字节数;出错返回-1。