今天学习了Linux的文件操作,现在来总结一下
我们知道Linux内的所有东西都是以文件形式存在的,包括设备,那么如何操作文件对我们来说就显得很重要,现在来总结一下Linux中的文件操作
Linux中编程时候的文件用文件描述符,0代表标准输入,1到表标准输出,2代表标准错误输出、
1.open函数
调用open函数可以打开或创建一个文件
成功返回文件描述符,出错返回-1;
#include <fcntl.h>
//int open(const char * pathname,int oflag,...); //函数原型,返回文件描述符
//第三个参数为...表示余下参数数量不定,根据oflag来决定
/*
* oflag有如下参数:
* O_RDONLY 只读打开
* O_WRONLY 只写打开
* O_RDWR 读写打开
-----------------------------
上面三个常量必须指定一个,而且可以搭配以下常量(用或操作'|'):
-----------------------------
* O_APPEND 写追加到文件尾端
* O_CREAT 如果文件不存在,则创建它,使用这个选项,需要第三个参数指定访问权限
* O_OEXCL 如同时使用O_CREATE,而文件存在,则出错。用于测试文件是否存在,不存在则创建
* O_TRUNC 如果文件存在,而且为只写或读写成功打开,则将其长度截段为0
* O_NOCTTY 如果pathname指的是终端设备,则不将该设备分配作为此进程的控制终端
* O_NONBLOCK 如果pathname是一个特殊文件(FIFO,块文件,字符文件),则设置为非阻塞模式
* O_DSYNC 每次write等待物理I/O操作完成
* O_RSYNC 使每一个以文件描述符作为参数的read操作等待
* O_SYNC 使每次write都等到物理I/O操作完成
*/
2.create函数
成功返回0,出错返回-1
#include <fcntl.h>
//int creat(const char * pathname,mode_t mode);
/*
* 早期UNIX系统的open函数没有O_CREATE选项所以才设这一个函数
* 现在这个函数其实可以被
* open(pathname,O_WRONLY | O_CREAT | O_TRUNC,mode);
* 代替
*/
3.close函数
#include <unistd.h>
/*
* int close(int filedes); //关闭文件描述符为filedes的file
* 这是手动关闭方法,关闭一个文件会释放该进程加载在该文件上的所有记录锁
* 但一个进程终止时,内核自动关闭它打开的所有文件
*/
4.lseek函数
#include <unistd.h>
/*
* off_t lseek(int filedes,off_t offset,int whence);
* lseek函数是在指定位置whence加上偏移量offset处开始读取字节数
* whence参数有如下三个参考值
* SEEK_SET 文件开始处偏移量
* SEEK_CUR 文件当前位置偏移量
* SEEK_END 文件末尾偏移量
*/
5.read和write函数
/*
* #include <unistd.h>
* ----------------------------------------------------------
* ssize_t read(int filedes,void * buf,size_t nbytes);
* 返回成功读到的字节数,如果读到文件末尾则返回0,出错返回-1
* ----------------------------------------------------------
* ssize_t write(int filedes,const void * buf,size_t nbytes);
* 返回成功写入的字节数,出错则返回-1
* ----------------------------------------------------------
* 两个函数都在内核执行,这两个函数为不带缓冲的I/O函数
*/
6.pread和pwrite函数
/*
* #include <unistd.h>
* ---------------------------------------------------
* ssize_t pread(int filedes,void * buf,size_t nbytes,off_t offset);
* 相当于顺序调用lseek和read,但是无法中断定位和读操作,而且不更新文件指针
* 返回读到的字节数,如果读到文件末尾,返回0,出错返回-1
* ---------------------------------------------------
* ssize_t pwrite(int filedes,const void * buf,size_t nbytes,off_t offset);
* 相当于顺序调用lseek和write,无法中断定位和写操作,而且不更新文件指针
* 返回成功写入的字节数,出错返回-1
* ---------------------------------------------------
* 这两个函数属于原子操作函数,也就是说函数内容要么都不做,要么都做
*/
7.dup和dup2函数
/*
* #include <unistd.h>
* int dup(int filedes);
* int dup2(int filedes,int filedes2);
* dup和dup2函数都可以用来复制一个现存的文件描述符
* 两个函数返回值:若成功则返回新的文件描述符,出错返回-1
* dup返回的新闻见描述符一定是当前可用文件描述符的最小值
* 用dup2则可以用filedes2参数指定新描述符的数值
* 如果filedes2已经打开,则先将其关闭。
* 如果filedes等于filedes2,则dup2返回filedes2,而不关闭它
* 这些函数返回的新文件描述符与参数filedes共享统一个文件表项
*/
8.sync,fsync和fdatasync函数
/*
* #include <unistd.h>
* int fsync(int filedes);
* 对单一文件起作用,并且等待写磁盘操作结束然后返回
* int fdatasync(int filedes);
* 它只影响文件的数据部分
* ----------------------------------------
* 上述两个函数:成功返回0,出错返回-1
* ----------------------------------------
* void sync(void);
* 只是把修改过的块缓冲区排入写队列然后就返回,不等待实际写磁盘操作完成
*/
9.fcntl函数
/*
* #include <fcntl.h>
* int fcntl(int filedes,int cmd, ...);//...表示不定参数
* fcntl的返回值与cmd有关,如果出错,所有命令都返回-1
* 其中cmd参数有如下值可选:
* F_DUPFD 复制文件描述符filedes
* F_GETFD 对应于filedes的文件描述符标志作为函数值返回
* F_SETFD 对于filedes设置文件描述符标志
* F_GETFL 对应与filedes的文件状态标志作为函数值返回,状态如open函数描述中状态一致
* F_SETFL 将文件状态标志设置为第三个参数的值
* F_GETOWN 取当前接收SIGIO和SIGURG信号的进程ID或进程组ID
* F_SETOWN 设置接收SIGIO和SIGURG信号的进程ID或进程组ID
* F_GETFK 根据lock描述决定是否上lock文件锁
* F_SETFK 设置lock描述的文件锁
* F_SETLKW 这是F_SETLK的阻塞版本,命令名中的W表示等待(wait),如果存在其他锁,则调用进程睡眠;如果捕捉到信号则睡眠中断
*/
10.ioctl函数
/*
* #include <unistd.h> //System V
* #include <sys/ioctl.h> //BSD and Linux
* #include <stropts.h> //XSI STREAMS
* -----------------------------------------------------------
* int ioctl(int filedes,int request, ...); //...表示省略参数
* -----------------------------------------------------------
* 本函数用于很多其他函数(如read,wirte,lseek等)都无法完成的I/O惨做
* 终端I/O的ioctl命令都需要头文件<termios.h>
* 主要用于STREAMS I/O系统
*/
11.stat,fstat和lstat函数
/*
* #include <sys/stat.h>
* int stat(const char / restrict pathname,struct stat * restrict buf);
* int fstat(int filedes,struct stat * buf);
* int lstat(const char * restrict pathname,struct stat * restrict buf);
* 三个函数成功返回0,出错返回-1
* stat返回与pathname路径名文件的有关信息
* fstat返回描述符文件的信息
* lstat返回符号链接有关信息
* 关于文件信息结构说明如下:
* struct stat{
* mode_t st_mode; //文件类型和权限
* ino_t st_ino; //i-node的编号
* dev_t st_dev; //文件设备号
* dev_t st_rdev; //特殊文件设备号
* nlink_t st_nlink; //链接数(如果为0且文件没有被占用则内核删除该文件)
* uid_t st_uid; //文件拥有者的用户ID
* gid_t st_gid; //文件拥有者的组ID
* off_t st_size; //普通文件的大小,字节计算
* time_t st_atime; //文件最后被访问的时间
* time_t st_mtime; //文件最后被修改的时间
* time_t st_ctime; //文件状态最后被修改的时间
* blksize_t st_blksize; //最大I/O的block数目
* blkcnt_t st_blocks; //该文件占用磁盘的blocks数目
*/
12.文件类型和权限
/*
* 文件类型有很多,他们以宏的形式定义在<sys/stat.h>中
* 把struct stat中的st_mode字段放入宏内即可
* S_ISREG() 普通文件
* S_ISDIR() 目录文件
* S_ISCHR() 字符特殊文件
* S_ISBLK() 块特殊文件
* S_ISFIFO() 管道或FIFO文件
* S_ISLNK() 符号链接
* S_ISSOCK() 套接字
* 实例:if (S_ISREG(st.st_mode)) printf("这是普通文件");
* 文件的访问权限也是存储在st_mode里面,设置访问位宏如下:
* S_IRUSR 用户-读
* S_IWUSR 用户-写
* S_IXUSR 用户-执行
* S_IRGRP 组-读
* S_IWGRP 组-写
* S_IXGRP 组-执行
* S_IROTH 其他-读
* S_IWOTH 其他-写
* S_IXOTH 其他-执行
* S_ISUID 执行时设置用户ID
* S_ISGID 执行时设置组ID
* S_ISVTX 保存正文(粘住位,如/tmp里面,可以修改自己文件,不可以修改别人文件)
* S_IRWXU 用户(所有者)读,写和执行
* S_IRWXG 组读,写和执行
* S_IRWXO 其他读,写和执行
*/
13.access函数
/*
* #include <unistd.h>
* int access(const char * pathname,int mode);
* 函数执行成功返回0,出错返回-1
* 该函数是按实际用户ID和实际组ID进行访问权限测试的
* 其中mode常量有如下值:
* R_OK 测试读权限
* W_OK 测试写权限
* X_OK 测试执行权限
* F_OK 测试文件是否存在
*/
14.umask函数
/*
* #include <sys/stat.h>
* mode_t umask(mode_t cmask);
* 该函数返回修改前文件的屏蔽值
* cmask指文件权限S_IRUSR,S_IWUSR等值或他们的异或
*/
15.chmod和fchmod函数
/*
* #include <sys/stat.h>
* int chmod(const char * pathname,mode_t mode);
* int fchmod(int filedes,mode_t mode);
* 成功返回0,出错返回-1;
* 两个函数用于改变文件访问权限
* chmod是在指定文件上进行操作,而fchmod是对已打开文件上进行操作
* 除了常见S_IRUSR等权限,mode还可以修改
* S_ISUID 执行时设置用户ID
* S_ISGID 执行时设置组ID
* S_ISVTX 保存正文(粘住位,如/tmp里面,可以修改自己文件,不可以修改别人文件)
* S_IRWXU 用户(所有者)读,写和执行
* S_IRWXG 组读,写和执行
* S_IRWXO 其他读,写和执行
*/
16.chown,fchown和lchown函数
/*
* #include <unistd.h>
* int chown(const char * pathname,uid_t owner,gid_t group); //修改指定路径文件拥有者
* int fchown(int filedes,uid_t owner,gid_t group); //修改已打开文件拥有者
* int lchown(const char * pathname,uid_owner,gid_group); //修改链接的拥有者,而不是链接目标文件的拥有者
* 成功返回0,出错返回-1;
* 如果owner或group中的任意一个为-1,则对应的ID不变
*/
17.truncate和ftruncate函数
/*
* #include <unistd.h>
* int truncate(const char * pathname,off_t length); //截短指定路径文件
* int ftruncate(int filedes,off_t length); //截短已打开文件
* 成功返回0,出错返回-1;
* 该函数用于截短文件,截短至length字节
* 如果之前文件长度大于length,则截短至length;小于则补0至长度为length
*/
18.link和unlink函数
/*
* #include <unistd.h>
* int link(const char * existingpath,const char * newpath);
* 成功返回0,出错返回-1
* 该函数用于创建一个指向现有文件或目录的链接,目录需要超级用户
* ---------------------------------------------------------
* int unlink(const char * pathname);
* 成功返回0,出错返回-1
* 该函数用于对指定路径锁引用的文件或目录的链接计数减1
* 当文件的链接计数为0,而且该文件没有被打开,内核会自动删除该文件
*/
19.remove和rename函数
/*
* #include <stdio.h>
* int remove(const char * pathname);
* 成功返回0,出错返回-1
* 用于删除一个文件或目录
* -----------------------------------------
* int rename(const char * oldname,const char * newname);
* 成功返回0,出错返回-1;
* 用于修改一个文件或目录的名字
* 注意,如果newname已存在,则会先删除原本的,然后再新建它
*/
20.symlink和readlink函数
/*
* #include <unistd.h>
* int symlink(const char * actualpath,const char * sympath);
* 成功返回0,出错返回-1
* 该函数用于创建一个指向actualpath的新目录项sympath符号链接
* ----------------------------------------------------------
* ssize_t readlink(const char * restrict pathname,char * restrict buf,size_t bufsize);
* 成功返回读到的字节数,出错返回-1
* 该函数用于读取符号链接本身的信息
*/
21.utime函数
/*
* #include <utime.h>
* int utime(const char * pathname,const struct utimebuf * times);
* 成功返回0,出错返回-1;
* 该函数用于修改文件的访问和修改时间
* 其二个参数的定义如下:
* struct utimebuf{
* time_t actime; //访问时间
* time_t modtime; //修改时间
* }
*/
22.mkdir和rmdir函数
/*
* #include <sys/stat.h>
* int mkdir(const char * pathname,mode_t mode);
* 成功返回0,出错返回-1
* 该函数用于创建一个空目录
* -----------------------------------------------
* #include <unistd.h>
* int rmdir(const char * pathname);
* 成功返回0,出错返回-1
* 该函数用于有删除一个空目录(目录非空执行失败)
*/
23.读取目录的函数
/*
* #include <dirent.h>
* DIR * opendir(const char * pathname); //用于打开目录,成功返回指针,出错返回NULL
* struct dirent * readdir(DIR * dp); //读取打开的目录,成功返回指针,若在目录结尾或出错返回NULL
* void rewinddir(DIR * dp); //重置目录读取
* int closedir(DIR * dp); //关闭目录读取,成功返回0,出错返回-1
* long telldir(DIR * dp); //返回与dp关联的目录中的当前位置
* void seekdir(DIR * dp,long loc); //设置目录的读取位置
* ---------------------------------------------------------
* 读取到的文件信息结构struct dirent定义如下:
* struct dirent{
* ino_t d_ino; //文件的i-node号码
* char d_name[NAME_MAX + 1]; //以null结尾的文件名
* }
*/
24.chdir、fchdir和getcwd函数
/*
* #include <unistd.h>
* int chdir(const char * pathname);
* int fchdir(int filedes);
* 两个函数成功返回0,出错返回-1
* 两个函数用于更改当前的工作目录
* 分别用pathname或打开文件描述符来指定新的当前工作目录
* ---------------------------------------------
* char * getcwd(char * buf,size_t size);
* 成功返回buf,出错返回NULL
* 该函数用于取得当前工作路径的绝对路径名
*/