美文网首页
文件和目录(三)

文件和目录(三)

作者: 千里山南 | 来源:发表于2016-01-31 17:40 被阅读38次

    2016-01-31

    link unlink remove rename函数

    任何一个文件可以有多个目录项指向其i节点。创建一个向现存文件的连接的方法是使用link函数
    int link(const char *existingpath, const char * newpath)
    int unlink(const char *pathname)
    如果newpath已经存在则返回出错
    只有超级用户进程可以常见指向一个目录的连接。其理由是这样做可能在文件系统中形成循环,大多数处理文件系统的公用程序都不能处理这种情况
    只有当连接数为0时该文件内容才可被删除。只要进程打开了该文件,其内容也不能被删除。
    unlink的这种特性经常被程序用来确保即使是在程序崩溃时,它所创建的临时文件也不会遗留下来。进程用open或者create创建提个文件然后立即调用unlink.
    我们也可以用remove函数解除对一个文件或者目录的连接,对于文件remove的功能与unlink相同,对于目录remove的功能与rmdir相同
    int remove(const char *pathname)
    文件或者目录用rename函数更名
    int rename(const char *oldname, const char * newname)
    如果oldname 是个文件,如果newname不是一个目录,如果其存在则删除。
    如果oldname使一个目录,那么为该目录更名。如果newname已经存在,则它必须因拥抱一个目录,而且该墓应当是空目录,现将其删除,然后将oldname更名为newname.
    如果oldname和newname引用同一个文件,则直接返回成功。

    符号连接

    符号连接是对文件的间接指针,它与硬连接不同。硬连接直接指向文件的i节点。引进符号连接的原因是为了避免硬链接的一些限制:硬链接要求连接和文件位于同一文件系统中。只有超级用户才能创建到目录的硬链接。符号连接一般用于将一个文件或者整个目录结构移到系统中其他某个位置。
    当使用以名字引用一个文件的函数时,应当了解该函数是够处理符号连接功能。使用符号连接可能在文件系统中引入循环,大多数查找路径名的函数在这种情况下都返回值为ELOOP的errno
    用open打开文件时,如果传递给函数的路径指定了一个符号连接,那么open跟随此连接到制定的文件。若连接文件不存在则打开失败。

    fynlink readlink函数

    symlink函数创建一个符号连接
    int symlink(const char *actualpath, const char *sympath)
    该函数并不要求actualpath已经存在,并且并不要求他们在同一个文件系统中,因为open函数跟随符号连接,所以需要有一种打开连接本身,并读该链接中的名字。readlink函数提供了这种功能

    文件的时间

    每个文件相关的三个时间值st_atime文件数据的最后存取时间,st_mtime文件数据的最后修改时间,st_ctime i节点状态的最后更改时间
    注意习惯改时间和更改状态时间之前的区别,修改时间是文件内容最后一次被修改的时间。更改状态的时间是该文件的i节点最后一次被修改的时间,系统并不保存对一个i节点最后一次存取时间,所以access和stat函数并不更这三个时间。系统管理员常常使用存取时间来删除在一定时间范围内没有村去过的文件。
    ls命令按这三个时间值中的一个排序进行显示。默认按文件修改时间排序,-u使用存取时间排序 -c使用更改状态时间排序
    读写一根文件只影响该文件的i节点而与父目录无关

    utime函数

    一个文件的存取和修改时间可以使用utime函数来更改
    int utime(const char *pathname, const struct utimbuf *times)
    struct utimebuf {
    time_t actime;//日历时间
    time_t modtime;
    }

    如果times是一个空指针,则寸拳时间和修改时间都设置为当前时间,若非空,设置为指定值。

    mkdir和rmdir函数

    mkdir创建目录,rmdir删除目录
    int mkdir(const char *pathname, mode_t mode)
    常见的错误是指定与文件相同的mode,但是对于目录通常至少要设置一个执行权限,以允许存取该目录中的文件名
    int rmdir(const char *pathname) 删除一个空目录

    读目录

    对某个目录具有存取许可权的人以用户都可以读该目录,但是只有内核才能写目录。
    DIR *opendir(const char *pathname) 若成功则返回指针,出错返回NULL
    struct dirent *readdir(DIR *dir); 成功则返回指针,若在目录尾或者出错返回NULL
    void rewinddir(DIR *dp)
    int closedir(DIR *dp) 成功返回0出错返回-1

    chdir fchdir getcwd函数

    每个进程都有一个当前工作目录,此目录是搜索所有相对路径的起点。当登陆Unix系统时,当前工作目录是口令文件中第6个字段。当前工作目录市金城的一个属性,起始目录是登录名的一个属性。进程滴啊用chdir或fchdir函数可以更改当前工作目录。
    int chdir(const char *pathname)
    int fchdir(int filedes)
    因为内核保持有当前工作目录的信息,所以我们应能取其当前值,不幸的是内核为每个进程只保存其当前工作目录的i节点编号以及设备标识,并不保存完整路径名。
    char *getcwd(char *buf, size_t size)此函数获取当前工作目录的据对路径。buf必须足够大能够容纳绝对路径加上null。

    特殊设备文件

    st_dev和st_rdev

    • 每个文件系统都由其主次设备号而为人所知。设备号所用的数据类型是基本系统数据类型dev_t
    • 系统中每个文件名的st_dev值是文件系统的设备号,该文件系统包含了改文件名和其对应的i节点
    • 只有字符特殊文件和块特殊文件才有st_rdev值,此值包含该实际设备的设备号

    POSIX中一般使用major和minor宏来从st_dev中取得主设备号和次设备号

    sync和fsync函数

    传统Unix实现在内核中设有换从存储器,大多数磁盘io都通过缓存进行。当将数据写到文件上时,通常该数据先有内核扶植到缓冲区,如果缓存尚未写满,则并不将其排入输出队列,而是等待其写满或者党内和需要重用该缓存以便存放其他磁盘数据块时,再将该缓存排入输出队列,然后待其到达队首才能进行实际的io操作,这种输出方式被称为延迟写,延迟写减少了磁盘读写次数,但是却降低了文件内容的更新速度,是的与写到文件中的数据在一段时间内并没有写到磁盘上。当系统发生故障时,这种延迟坑你造成文件更新内容的丢失。为了保证磁盘上世纪文件系统与缓存中内容的一致性,Unix系统提供了sync和fsync两个系统调用函数
    void sync(void)将所有修改过的块的缓存排入写队列。系统精灵进程一般每隔30秒调用一次sync函数
    fsync只是用用单个文件,等待它io结束然后返回。gsync可用于数据库这样的应用,它确保修改过的块立即写到磁盘上。

    相关文章

      网友评论

          本文标题:文件和目录(三)

          本文链接:https://www.haomeiwen.com/subject/nmkskttx.html