APUE 2 文件和目录

2018-04-04  本文已影响0人  openex

本文代码实现采用golang的syscall包,其通常会包装一层系统调用不过大体相似


1.文件属性结构 Stat_t

文件类型 描述
普通文件 可能是文本或二进制
目录文件 包含该目录内的文件名,和有关这些文件信息的指针
块特殊文件 提供对设备带缓冲的访问
字特殊文件 提供对设备不带缓冲的访问,每次访问长度可变
FIFO 命名管道,用于进程间通信
套接字 用于进程间的网络通信,也可用于同一台宿主机进程间非网络通信
符号链接 指向另一个文件

文件的类型

文件类型 描述
普通文件 可能是文本或二进制
目录文件 包含该目录内的文件名,和有关这些文件信息的指针
块特殊文件 提供对设备带缓冲的访问
字特殊文件 提供对设备不带缓冲的访问,每次访问长度可变
FIFO 命名管道,用于进程间通信
套接字 用于进程间的网络通信,也可用于同一台宿主机进程间非网络通信
符号链接 指向另一个文件

描述文件属性的结构体Stat_t

type Stat_t struct {
        Dev       uint64  //设备号,文件(以及i节点)在此文件系统中
        Ino       uint64 //inode号
        Nlink     uint64 //链接数
        Mode      uint32 //文件类型&访问权限
        Uid       uint32 //属主ID
        Gid       uint32 //属组ID
        X__pad0   int32
        Rdev      uint64 //实际设备号,只有块字特殊文件才有此值
        Size      int64 //文件大小,byte单位
        Blksize   int64 //最佳I/O块大小
        Blocks    int64 //已分配块数(512字节块或其他,根据不同系统可能不同)
        Atim      Timespec //访问时间
        Mtim      Timespec //修改内容时间
        Ctim      Timespec //修改文件属性时间
        X__unused [3]int64
}

type Timespec struct {
        Sec  int64 //秒
        Nsec int64 //纳秒
}

2.查看文件属性信息stat、fstat、lstat

func Stat(path string, stat *Stat_t) (err error)
func Fstat(fd int, stat *Stat_t) (err error)
func Lstat(path string, stat *Stat_t) (err error)

Stat函数根据传入的path,读取文件属性写至stat,注意Stat函数会追踪符号链接至真实文件
Fstat函数根据当前已打开的文件描述符,读取属性至stat
Lstat函数同Stat,但不会追踪链接文件,直接返回符号链接的属性

3.进程相关的ID

4.4

通常情况下,启动一个进程时会将有效ID设置为实际ID
但是在文件Mode属性中存在特殊的位设置用户设置组,如若设置了该位置,启动一个进程时有效ID会被设置为文件所有ID

4.文件访问权限

所有类型的文件均具有访问权限设置,其值在Stat_t中的Mode


4.5

对于不同类型的文件,再此处做2类区分,文件和目录:

5.创建新文件和目录的所有权

新文件的用户ID设置为当前进程有效用户ID
组ID取决于其所属的目录的设置组ID是否有效,若有效则新创建的文件的组ID为该目录的组ID;否则为进程的有效组ID

6.访问权限测试 access和faccessat

func Access(path string, mode uint32) (err error)
func Faccessat(dirfd int, path string, mode uint32, flags int) (err error)
//R_OK=4, W_OK=2, X_OK=1, F_OK=0   mode只可以为对应的整数值

注意:golang中的Access参数mode不可用C中的测试宏(R_OK等),等效可用对应的整数值。如上边的注释内容

如果想自行进行访问权限的检测,如通过实际ID来进行检测等
Access与Faccessat区别:

7.屏蔽字umask

func Umask(mask int) (oldmask int)
4-7

当创建文件时,将和umask进行与非操作(类似网络掩码),使创建的文件不含有某些权限

注意:修改进程的umask不会影响其父进程(通常为shell)

8.修改文件模式属性 Chmod、Fchmod、Fchmodat

func Chmod(path string, mode uint32) (err error)
func Fchmod(fd int, mode uint32) (err error)
func Fchmodat(dirfd int, path string, mode uint32, flags int) (err error)

3个函数区别:

mode 常量

VTX

粘着位 S_ISVTX:

9.修改文件属主(组) chown系列

func Chown(path string, uid int, gid int) (err error)
func Fchown(fd int, uid int, gid int) (err error)
func Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error)
func Lchown(path string, uid int, gid int) (err error)

这四个函数与其他类似函数的变种概念相近
除了Fchown(根据打开的文件)其他的均可由Fchownat来包装形成
影响Fchownat行为的参数:

10.文件长度

文件属性中的Size描述了文件的长度

文件属性中的Blocks描述了文件所占512字节块(或其他)数目
关于产生文件空洞的现象(Size>>Blocks*N),空洞未分配实际磁盘空间,但使用Read函数会把空洞位读出0,既会读出Size个字符

11.文件截断

func Truncate(path string, length int64) (err error)
func Ftruncate(fd int, length int64) (err error)

根据指定的length将目标文件进行截断,使文件长度变成length,若原长度小于length的话将产生空洞

12.文件系统*

以Berkeley快速文件系统为例


123

磁盘可划分为多个分区,每个分区包含一个文件系统。本章值得注意的是i节点和数据块(含目录块)
i节点包含文件stat结构中的大多数信息
目录块含目录中各文件名和对应的i节点地址


i节点

当创建一个新目录testdir后文件系统内相关结构


结构

13.硬链接 link

func Link(oldpath string, newpath string) (err error)
func Linkat(olddirfd int, oldpath string, newdirfd int, newpath string, flags int) (err error)
func Unlink(path string) error
func Unlinkat(dirfd int, path string, flags int) (err error)

如上文文件系统的描述,任何一个文件可以有多个目录项指向其i节点

创建硬链接(目录项)

删除硬链接

14 重命名 rename和renameat

func Rename(oldpath string, newpath string) (err error)
func Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error)

针对待重命名文件的类型(文件或目录)有如下几种情况

15 符号链接

一种特殊的文件类型,是类似于文件硬链接的文件间接指针,与硬链接不同:

不同的系统调用对于符号链接是否跟随情况不一,如图


跟随情况

创建符号链接

func Symlink(oldpath string, newpath string) (err error)
func Symlinkat(oldpath string, newdirfd int, newpath string) (err error)

创建oldpath指向newpath的符号链接,Symlinkat的newdirfd为AT_FDCWD时两个函数相同

因为open函数会跟随符号链接,所以读取符号链接的内容存在独立的函数

func Readlink(path string, buf []byte) (n int, err error)
func Readlinkat(dirfd int, path string, buf []byte) (n int, err error)

函数会将符号链接的内容读入buf中,值为oldpath的路径名(不以null结尾)

16 文件的时间

Atim      Timespec //访问时间
Mtim      Timespec //修改内容时间
Ctim      Timespec //修改文件属性时间

type Timespec struct {
        Sec  int64 //秒
        Nsec int64 //纳秒
}

正如前文描述的文件属性

各种函数对文件时间的影响:

对时间影响

修改文件时间:

func Futimes(fd int, tv []Timeval) (err error) //打开的描述符
func Futimesat(dirfd int, path string, tv []Timeval) error //可指定目录描述符和path
func Utimes(path string, tv []Timeval) error //相对路径AT_FDCWD或绝对路径

type Timeval struct {
    Sec  int64
    Usec int64
}

17 创建目录


func Mkdir(path string, mode uint32) (err error)
func Mkdirat(dirfd int, path string, mode uint32) (err error)
func Rmdir(path string) error

注意创建目录时umask的影响,和是否支持设置组
Rmdir实际由Unlinkat实现:

func Rmdir(path string) error {
    return Unlinkat(AT_FDCWD, path, AT_REMOVEDIR)
}

18 更改(获取)当前工作目录 chdir fchdir getcwd

func Chdir(path string) (err error)
func Fchdir(fd int) (err error)
func Getcwd(buf []byte) (n int, err error)

19.文件访问权限小结

这里写图片描述
上一篇下一篇

猜你喜欢

热点阅读