首页 > 代码库 > Linux文件操作的常用系统函数说明

Linux文件操作的常用系统函数说明

1. open打开文件 (man 2 open 查看)

int open(const char *pathname, int flags); //pathname文件名(路径);flags打开模式,有O_RDONLY, O_WRONLY, O_RDWR

  int open(const char *pathname, int flags, mode_t mode); //该函数一般用于创建新文件,flags添加O_CREAT,比如:O_RDWR|O_CREAT
        int creat(const char *pathname, mode_t mode); //创建新文件,mode权限说明,比如0644(八进制,取反后和umask做与运算得到真正结果)

返回值:成功返回文件描述符fd,失败返回-1 。 

举例说明:

int fd = open("test.txt", O_WRONLY); //只写的方式打开test.txt,返回文件描述符

附:文件描述符说明(32位机器上文件描述符从0到1023): 0表示标准输入,1表示表示输出,2表示表示错误;我们程序打开的从3开始,每次总是使用最小的。

2. read文件读取 (man 2 write 查看)

ssize_t read(int fd, void *buf, size_t count); //ssize_t有符号整数;fd文件描述符;buf传出参数,读取的内容就在buf里;count表示buf的长度

返回值:大于0表示读取的字节数,等于0表示读取完,-1表示读取失败 

3. write文件写入 (man 2 write 查看)

ssize_t  write(int  fd,  const  void  *buf, size_t count); //buf需要写入的内容,count需要写入的内容的长度;ssize_t有符号整数;size_t无符号整数

返回值:大于表示写入的字节数,0表示没有写入任何数据,-1表示写入失败

4. lseek移动文件指针 (man 2 lseek 查看)

off_t lseek(int fd, off_t offset, int whence);  //fd文件描述符,offset移动偏移量,whence移动参考点

 whence的三个取值:SEEK_SET文件开始位置,SEEK_CUR表示指针当前位置,SEEK_END文件结束位置

返回值:大于等于0表示离文件开始处的偏移量,-1表示失败 

附:该函数可用于扩容,比如 lseek(fd,100,SEEK_END);表示扩容100个字节,但是要执行一次写操作扩容才生效。

5. stat获取一个文件的信息 (man 2 stat 查看)

int stat(const char *path, struct stat *buf); //path文件路径;buf传出参数,获取的文件信息就在buf里面

int fstat(int fd, struct stat *buf); //fd文件描述符

int lstat(const char *path, struct stat *buf); //lstat和stat的区别只在于符号链接文件,lstat读取符号链接文件,stat读取符号链接对应的源文件

返回值:成功返回0;失败返回-1 。

附:下面说明一下 struct stat结构体的组成

struct stat { dev_t st_dev; /* ID of device containing file 设备ID*/ ino_t st_ino; /* inode number Inode节点*/ mode_t st_mode; /* protection 文件的类型和存取的权限等等(这个字段很重要,该字段的具体说明请看man文档)*/

nlink_t st_nlink; /* number of hard links 硬链接数*/ uid_t st_uid; /* user ID of owner 用户ID*/ gid_t st_gid; /* group ID of owner 组ID*/ dev_t st_rdev; /* device ID (if special file) 若此文件为设备文件,则为其设备编号*/

off_t st_size; /* total size, in bytes 文件字节数,即文件大小*/ blksize_t st_blksize; /* blocksize for file system I/O 块的大小,即文件系统的I/O缓冲区大小*/

blkcnt_t st_blocks; /* number of 512B blocks allocated 块的数量*/ time_t st_atime; /* time of last access 最后一次访问时间*/ time_t st_mtime; /* time of last modification 最后一次修改时间*/ time_t st_ctime; /* time of last status change 最后一次更改时间*/ };

结构体struct stat的st_mode的说明:

...check the file type using the st_mode field://使用st_mode检查文件类型的宏定义如下

            S_ISREG //普通文件(m)  is it a regular file?
            S_ISDIR //目录(m)  directory?
            S_ISCHR //字符设备(m)  character device?
            S_ISBLK //块设备(m)  block device?
            S_ISFIFO //管道(m) FIFO (named pipe)?
            S_ISLNK //符号链接(m)  symbolic     link?     (Not  in POSIX.1-1996.)
            S_ISSOCK //套接字(m) socket? (Not in POSIX.1-1996.)
举例说明:

switch (sb.st_mode & S_IFMT){ //S_IFMT是文件类型掩码,其值是八进制170000

case S_IFBLK: printf("block device\n"); break;

case S_IFCHR: printf("character device\n"); break;

case S_IFDIR: printf("directory\n"); break;

case S_IFIFO: printf("FIFO/pipe\n"); break;

case S_IFLNK: printf("symlink\n"); b reak;

case S_IFREG: printf("regular file\n"); break;

case S_IFSOCK: printf("socket\n"); break;

default: printf("unknown?\n"); break;

 附:S_IRWXU文件所有者权限掩码,其值为00700;S_IRWXG组权限掩码,其值为00070;S_IRWXO其他人权限掩码,其值为00007;具体看man 手册。用法都是一样,以S_IRWXU为例,如下所示:

switch(sb.st_mode & S_IRWXU){

case:S_IRUSR printf("owner has read permission\n"); break;

case:S_IWUSR printf("owner has wirte permission\n"); break;
case:S_IXUSR printf("owner has execute permission\n"); break;

6. access检查文件权限 (man 2 access 查看)

int access(const char *pathname, int mode); //pathname文件名称,mode权限

返回值:所有权限被允许返回0;只要有一个权限不允许的就返回-1,错误也是返回-1; 

mode的值说明:

要不是F_OK :表示文件是否存在

要不是R_OK | W_OK | X_OK ,可以是一个或者多个,多个之间按位与;R_OK是否可读,W_OK是否可写,X_OK是否可执行

7. chmod改变文件权限

int chmod(const char *path, mode_t mode); //path文件路径;mode_t整数,mode权限,必须是一个八进制数,或者使用预定义宏,具体查看man手册

int fchmod(int fd, mode_t mode); //fd文件描述符

返回值:成功返回0;失败返回-1 。 

8. chown改变文件所有者 (一般需要root权限才能操作成功)

int chown(const char *path, uid_t owner, gid_t group); //穿透符号链接;文件路径

int fchown(int fd, uid_t owner, gid_t group); //直接文件操作;fd文件描述符

int lchown(const char *path, uid_t owner, gid_t group); //不穿透符号链接;文件路径

返回值:成功返回0;失败返回-1 。

9. truncate更改文件到指定的长度

int truncate(const char *path, off_t length); //path文件路径,必须有写权限;length文件长度,单位字节数

int ftruncate(int fd, off_t length);//fd文件描述符,文件必须是打开状态

返回值:成功返回0;失败返回-1 。

附:该函数可用于文件扩容,不需要写一次才能生效;lseek函数扩容需要写一次才能生效。

10. link创建一个硬链接

int link(const char *oldpath, const char *newpath); //oldpath源文件,newpath要创建的硬链接的路径

返回值:成功返回0;失败返回-1 。

11. symlink创建一个软连接

int symlink(const char *oldpath, const char *newpath); //oldpath源文件路径,newpath软连接路径

返回值:成功返回0;失败返回-1 。

12. readlink读取软连接对应的文件名(不是读取源文件的内容) 

ssize_t readlink(const char *path, char *buf, size_t buf-siz); //path软连接路径;buf传出参数,buf-siz是buf的长度;读取的内容就在buf里面

返回值:成功返回读取的内容的长度,失败返回-1 。

13. unlink删除一个链接

如果是符号链接,删除符号链接;

如果是硬链接,硬链接数减1;当减为0时,释放数据块和Inode;

附:如果硬链接数为0,但有进程占用着该文件,则必须等进程关闭该文件,才会真正地删除该文件,可利用这个特性创建临时文件,

先open或者creat创建一个文件,然后接着unlink。这样进程关闭该文件或者进程退出时,该文件会自动删除。 

int unlink(const char *pathname); //pathname文件路径

返回值:成功返回0;失败返回-1 。

14. rename文件重命名

int rename(const char *oldpath, const char *newpath); //oldpath原文件,newpath新的文件

返回值:成功返回0;失败返回-1 。

15. fcntl操作文件描述符(记忆:file control)

int fcntl(int fd, int cmd, ... /* arg */ ); //fd文件描述符;cmd命令;第三个是可变参数,可选的

返回值:成功返回大于等于0,根据cmd的取值返回不同的含义值;失败返回-1 。 

举例说明:

int fcntl(int fd, int cmd);

int fcntl(int fd, int cmd, long arg);

int fcntl(int fd, int cmd, struct flock *lock); 

根据功能分类确定cmd的值:

1.复制一个现有的文件描述符,cmd为F_DUPFD

2.获取或设置文件描述符标记,cmd为F_GETFD、F_SETFD

3.获取或设置文件状态标记,cmd为F_GETFL、F_SETFL

4.获取或设置锁,cmd为F_SETLK、F_SETLKW、F_GETLK

5.获取或设置异步IO所有权,cmd为F_GETOWN、F_SETOWN、F_GETSIG、F_SETSIG

6.lease、File and directory change notification等等,具体查看man手册。 

 

Linux文件操作的常用系统函数说明