Linux文件管理(基本文件I/O,文件属性操作,目录操作)

23 阅读5分钟

Linux文件管理

@[toc]

文件描述符号

基本I/O函数包括

  • open() / creat(), close(), read(), write(), lseek()
  • dup()/dup2()
  • fcntl()
  • ioctl()

文件操作

​ 任何打开的文件都会被分配一个唯一的非负整数fd代表这个打开的文件,其中文件描述符0~2已经在进程运行时默认打开了,所以自定义的文件描述符都从3之后开始

  • STDIN_FILENO(0)
  • STDOUT_FILENO(1)
  • STDERR_FILENO(2)

​ 能够打开和创建文件的函数是opencreate

fd = int open(const char *pathname,int flags,mode_t mode);
fd = int create(const char *pathname,mode_t mode);

​ 用flag的方式在路径pathname处打开或者创建一个文件

flag的参数主要包括下面几种

  • O_RDONLY :只读打开
  • O_WRONLY:只写打开
  • O_RDWR:可读可写
  • O_APPEND:追加内容
  • O_TRUNC:重写内容
  • O_CREATE:如果不存在就创建文件

​ 由flags参数我们可以看出当我们使用open函数并且flags参数设置为O_WRONLY|O_TRUNC|O_CREAT的时候就和create函数类似了

mode的参数主要包括下面几种

  • S_IRUSR:所有者读权限
  • S_IWUSR:所有者写权限
  • S_IXUSR:所有者执行权限
  • S_IREXU:所有者读、写、执行权限

下面也都类似:

  • S_IRGRP:同组读权限
  • S_IROTH:其他用户读权限

​ 文件关闭使用close()函数

int closte(int fd);

​ 同样也是使用文件描述符fd进行关闭文件指针


​ 文件读取函数read()

ssize_t read(int fd,void *buf,size_t count);

​ 从fd指向的文件中读取count个字节到字符串buf

​ 返回值为0到文件尾,出错为-1


​ 文件写入函数write()

ssize_t write(int fd,void *buf,size_t count);

​ 将以buf为起始地址的count个字节写入到fd指向的文件中

​ 出错返回值为-1


​ 文件定位函数lseek()

off_T lseek(int fildes,off_t offset,int whence);

​ 将fildes指向的文件的文件描述符从whence的位置开始偏移offset个位置

whence的参数有

  • SEEK_SET:文件头开始
  • SEEK_END:文件末尾
  • SEEK_CUR:文件当前位置

stat为存储着文件属性的结构体,st_mode存储着文件类型和权限

​ 获取文件属性函数

int stat(const char *filename,struct stat *buf);
int fstat(int fd,struct stat *buf);
int lstat(const char *filename,struct stat *buf);

​ 获取路径filename的文件基本属性buf

​ 正确返回0,错误返回-1并设置errno

​ 其中fstat使用的是文件描述符,lstat使用是硬链接名称,lstat()返回连接自身状态

测试文件类型的宏

S_ISREG(statBuf.st_mode)

  • S_ISREG()
  • S_ISDIR()
  • S_ISCHAR()
  • S_ISBLK()
  • S_ISFIFO()
  • S_ISLNK()
  • S_ISSOCK()

测试文件权限直接按位与运算

buf.st_mode & S_IRUSR

access函数判断实际用户和实际组对文件的存取权限

int access(const char *pathname,int mode);

mode的参数

  • F_OK 为 0 是都存在
  • R_OK 为 4
  • W_OK 为 2
  • X_OK 为 1

R_OK|W_OK|X_OK 可以使用


​ 复制文件描述符

int dup(int oldfd);
int dup2(int oldfd,int newfd);

dup函数就是返回一个指向oldfd的文件描述符,二者共享数据结构

dup2主要强调必须是一个已经存在的可用的文件描述符newfd,两个描述符指向同一文件


根据文件描述符进行调用

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

cmd是操作命令,arglock是参数

  • F_DUPFD:复制文件描述符
  • FD_CLOEXEC:设置close-on-exec标志
  • F_GETFD:读取文件描述符标志
  • F_SETFD:设置文件描述符标志
  • F_GETFL:读取文件状态标志
  • F_SETFL:设置文件状态标志
  • F_GETLK:获取记录锁
  • F_SETLK :释放记录锁
  • F_SETLKW:测试记录锁

​ fcntl(oldfd,F_DUPFD,0) 等于 dup函数


​ 硬链接相当于建立一个新的文件别名,但是不可以在不同文件系统创建并且只能由超级用户在可以为目录创建硬链接

int link(const char *oldpath,const char *newpath);
int unlink(const char *oldpath);

​ 软连接相当于创建一个新文件也就是一个快捷方式,该文件指向源文件的位置,可以链接任意文件或目录

int symlink(const char *oldpath,const char *newpath);
int readlink(const char *path,char *buf,size_bufsiz);

readlink读取软连接本身的内容也就是指向文件的文件名,返回读取的字节数


umask()函数为进程设置文件存取权限屏蔽字

mode_t umask(mode_t mask);

umask是一种文件保护机制,每个创建的新文件的初始访问模式为mode & ~umask


chmodfchmod函数更改文件权限

int chmod(const char *path,mode_t mode);
int fchmod(int fildes,mode_mode);

​ 改变文件的权限


​ 改变文件宿主

int chown(const char *path,uid_t owner,gid_t group);
int fchown(const char *path,uid_t owner,gid_t group);
int lchown(const char *path,uid_t owner,gid_t group);

​ 若path为符号连接, lchown()改变连接本身的所有者或组,chown()则改变连接所指向文件的所有者或组

目录操作

操作目录

创建/删除目录

  • mkdir()/rmdir() 更改/获取目录
  • chdir()/fchdir(), getcwd() 读取目录信息
  • opendir()/closedir()
  • readdir()
  • telldir()
  • seekdir()

​ 创建和删除目录文件

int mkdir(const char *pathname, mode_t mode);
int rmdir(const char *pathname);

chdirfchdir改变工作目录

getcwd返回当前工作目录的绝对路径:成功返回buf失败返回NULL

​ 如果参数bufnull则会根据size自动开辟空间;

​ 如果size也为0,则会根据当前工作目录自动配置内存

int chdir(const char *path);
int fchdir(int fd);
char *getcwd(char *buf,size_t size);

读取目录信息

数据结构

  • DIR, struct dirent 基本操作
  • opendir()/closedir()
  • readdir()
  • telldir()
  • seekdir()

DIR是一个目录流对象

ino_t d_ino; /* inode号*/ char d_name[NAME_MAX + 1]; /* 文件名*/


​ 打开关闭目录

DIR *opendir(const char *name);
int closedir(DIR *dir);

​ 读取目录文件信息

struct dirent *readdir(DIR *dir);
struct dirent   
{   
  long d_ino; /* inode number 索引节点号 */  
    off_t d_off; /* offset to this dirent 在目录文件中的偏移 */  
    unsigned short d_reclen; /* length of this d_name 文件名长 */  
    unsigned char d_type; /* the type of d_name 文件类型 */     
    char d_name [NAME_MAX+1]; /* file name (null-terminated) 文件名,最长255字符 */  
}  

​ 获取目录流读取位置

long telldir(DIR *dirp);
void seekdir(DIR *dirp,long loc);

telldir()用来查询当前位置

seekdir()用来设置参数dir目录流读取位置,在调用readdir()时便从此新位置开始读取。参数offset 代表距离目录文件开头的偏移量