linux学习笔记之文件结构和函数

 本文参考《UNIX环境高级编程》

 

一、基础介绍。

1:文件的构成。

  1,首先声明,这里的文件和目录,表示普通的文件和目录。不确定是否可以应用到:设备,管道等特殊形式的文件(UNIX把它们也当作文件处理)。

  2,目录的构成:v节点编号和文件名。

    1)v节点:文件系统相关的节点。文件类型,各类文件操作函数指针。但目录中包含的是节点编号,不是节点本身。

  3,文件的构成:v节点和i节点。

    1)i节点:文件所有者,长度,磁盘实际所在位置指针等

    2)linux中,没有v节点,只有两个i节点。一个和文件系统相关,一个无关。

    3)链接文件的实际内容(数据块数据)为实际文件的文件名

2:文件描述符:在进程中,用来搜索文件的索引值。

  1,进程查找文件需要:记录表,文件表,V节点表。

    1)每个进程都会有一张记录表。文件描述符占用记录标中的一项。每一项会对应一个文件表的指针。

    2)文件表:记录文件状态,当前偏移量,v节点指针。

      1.文件状态表示:读写,添写,同步,阻塞...

  2,通过文件描述符查找文件的流程。

    1)通过文件描述符 —— 文件表 —— 找到v节点 —— 找到数据i节点。

  3,描述符是数值上为 非负整数。

  3,标准输入,标准输出,标准错误通常占用0,1,2这3个端口。很多shell和应用程序都默认支持此规则。所以如果更改此规则可能会导致系统和程序无法使用。

文件               对应描述符          POSIX的宏(include<unistd.h>) 
standard input、 0          STDIN_FILENO standard output    1          STDOUT_FILENO standard error     2          STDERR_FILENO

  4,宏OPEN_MAX 定义了最大打开文件数。描述符最大值为:OPEN_MAX-1

 

 

二、相关操作函数。

1:函数列表。

1 打开文件

  open(const char *path, int oflag, mode_t mode);

  openat(int fd, const char *path, int oflag, mode_t mode);

  // 1 fd:文件描述符。当openat函数第二参数path为相对路径时使用。得到相对路径的前置路径。

  // 2 oflag:有5个基本常量参数(不可多选),以及一些可选常量参数。

  // 3 openat函数使用:可以使用相对路径来访问文件,使函数更为灵活。

2 创建/删除一个文件

  creat(const char *path, mode_t mode ), close( int fd )

  // 1 creat函数等效于open(path, O_WRONLY| O_CREAT | O_TURNC, mode )

  // 2 关闭文件时,还会释放该进程在文件上添加的记录锁。

  // 3 当进程结束时,内核会自动关闭关联文件。

3 读/写 文件

  size_t read( int fd, void *buf, size_t nbytes );

  size_t write( int fd, const void *buf, size_t nbytes );

  // 1 read函数中返回值为 读到的字数, 第二参数保存 读到的字符的起始位置的指针。

  // 2 两个函数出错时,返回值为-1。

  // 3 write函数仅将数据写入缓存。写入磁盘时间由系统控制。如期望立即写入,需要设置:O_SYNC。

4 设置文件偏移量(针对已打开文件)

  lseek( int fd, off_t offset, int whence )

  // 1 whence有三个选项:SEEK_SET / CUR / END 分别表示 偏移量从  开始处 / 当前为指 / 结束点  开始。

  // 2 部分操作系统默认: SEEK_SET / CUR / END 分别为 0 / 1 / 2。

5 复制现有的文件描述符。

  int dup( int fd );

  int dup2( int fd, int fd2 );

  // 1 需要包含"unistd.h"头文件

  // 2 复制一个现有文件描述符 到 当前最小空余的文件描述符位。

6 将缓存区写入磁盘

  // 默认保存在缓冲区,等待内核写入。

  int sync( int fd );  // 发送写入指令,但不等待写返回。

  int fsync( int  fd ); //发送写入指令,并等待返回。

  int fdatasync( int fd ); //仅更新数据部分,不更新文件属性。

7 设置文件属性(针对已打开文件)

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

  // 1 复制一个已有描述符。

  // 2 get/set 文件描述符/文件状态标志/异步IO所有权/记录锁。

  // 3 修改 文件描述符/文件状态标志位时,注意先获取,确定正确,再赋值。防止出错。

8 获取文件相关信息。

  int stat( const char *restrict pathname, struct stat *restrict buf )

  int fstat( int fd, struct stat *restrict buf )

  int lstat( const char *restrict pathname, struct stat *restrict buf )

  int fstatat( int fd, const char *restrict pathname, struct stat *restrict buf, int flag )

  // 1 结构体 stat 保存 文件有关的信息。

  // 2 fstatat函数根据 参数flag 来决定具体作用。是上三种函数的集合体。

  // 3 lstat可以用来获取 符号链接 类型的文件的信息。

9 检测实际用户/组对文件的权限。

  int access( const char *pathname, int mode )

  int faccssat( int fd, const char *pathname, int mode, int flag )

  // 1 return : success is 0, failure is -1

  // 2 通常是因为设置ID,导致有效ID和实际ID不同时,才会使用。

  // 3 faccessat函数的 参数flag 设置为 AT_EACCESS 时,检测的是有效ID 而非实际。

10 设置屏蔽字。

  mode_t umask( mode_t cmask );

  // 1 设置屏蔽字。进程创建一个文件时,使用此屏蔽字来确定该文件的读写权限

  // 2 使用四个8进制数表示。分别为:文件类型,用户权限,组权限,其他组权限。

11 更改现有文件权限

  int chmod( const char* pathname, mode_t mode )

  int fchmod( int fd, mode_t mode )

  int fchmodat( int fd, const char *pathname, mode_t mode, int flag )

  // 1 flag 为 AT_SYMLINK_NOFOLLOW时,函数不跟随符号链接。

12 更改用户/组ID

  int chown( const char *pathname, uid_t owner, gid_t group )

  int fchown( int fd, uid_t owner, gid_t group )

  int fchownat( int fd, const char* pathname, uid_t owner, gid_t group, int flag )

  int lchown( const char* pathname, uid_ owner, gid_t group )

13 设置文件大小。

  int truncate( const char* pathname, off_t length )

  int ftruncate( int fd, off_t length )

14 增加/删除文件链接

  int link( const char* existingpath, const char* newpath)

  int linkat( int efd, const char* existingpath, int nfd, const char* newpath, int flag)

  int unlink( const char* pathname)

  int unlinkat( int fd, const char *pathname, int flag)

  int remove( const char* pathname )    // 删除文件需求:链接计数器为0,文件为关闭状态

  // 1 当由进程打开文件时,文件无法被删除。

  // 2 流程:关闭一个文件时,内核首先检查打开文件的进程个数;如果计数为0,内核再检查其链接计数,如果链接计数也为0,则删除该文件。

  // 3 该特性可以用来保证,临时文件不会被遗留下来。(因为进程关闭后,两个计数都为0)。

15 文件重命名

  int rename( const char *oldname, const char* newname )

  int renameat( int oldfd, const char *oldname, int newfd, const char* newname )

  // 1 不能对文件 ‘.’/‘..’ 两个文件进行重命名。

16 创建一个符号链接

  int symlink(const char *actualpath, const char *sympath )

  int symlinkat(const char *actualpath, int fd, const char *sympath )

17 读取符号链接本身

  ssize_t readlink( const char *restrict pathname, char *restrict buf )

  ssize_t readlinkat( int fd,  const char *restrict pathname, char *restrict buf, size_t bufsize )

18 更改文件的访问和修改时间。

  int futimens( int fd, const struct timespac time[2] )

  int utimensat( int fd, const char *path, const struct timespac times[2], int flag)

  int utimes( const char* pathname, const struct timeval times[2] )

  // 1 time参数中,第一个为访问时间,第二个为修改时间。

19 创建/删除目录

  int mkdir( const char* pathname, mode_t mode)

  int mkdirat( int fd, const char* pathname, mode_t mode)

  int rmdir( const char *pathname )

  // 1 需注意,rmdir的执行规则(进程打开计数,链接计数等)。

20 更改当前工作目录(HOME)

  int chdir( const char * pathname );

  int fchdir( int fd );

  char* getcwd( char *buf, size_t size );  //通过 相对路径 得到 绝对路径。 

2:历史遗留问题:高编3章后习题无法理解。待看完后重新尝试解决。

你可能感兴趣的:(linux)