首页 > 代码库 > unix环境高级编程笔记(5)—— 文件和目录(2)

unix环境高级编程笔记(5)—— 文件和目录(2)

1 文件截短

有时我们需要把文件尾端处截去一些数据以缩短文件,将一个文件清0是一个特例。在打开文件时使用O_TRUNC标志可以做到这一点。

#include <unistd.h>int truncate(const char *pathname,off_t length);int ftruncate(int filedes,off_t length);                                        成功返回0,出错返回-1.

如果length 小于文件长度,则使文件长度截断至length,剩下的不可访问。如果length大于文件长度,则与系统的实现有关,可能把原文件尾到现在文件尾的数据读作0(形成空洞)。

2 link、unlink、remove和rename函数

2.1 link、unlink函数

#include <unistd.h>int link(const char *existingpath,const char *newpath);int unlink(const char *pathname);                                            成功返回0、出错返回-1.

link创建一个新目录项newpath,它引用现有的文件existingpath,如果newpath已经存在则出错。

unlink 使文件pathname所引用文件的链接计数减1.如果到0则删除该文件。但是,只要有进程打开了该文件,其内容也不会被删除。关闭一个文件时,内核先检查打开文件的进程数,如果达到0,再检查其链接数,如果也为0就删除该文件。

unlink的这种性质经常被用来确保程序崩溃时,它所创建的临时文件也不会留下来,先用open打开临时文件,然会对它unlink。等进程结束或者崩溃时,文件自动被删除。

如果pathname是符号链接,unlink删除该符号链接而不会删除该符号链接所指向的文件。

2.2 remove函数

我们也可以用remove解除对一个文件或目录的链接。

#include <stdio.h>int remove(const char *pathname);                                成功返回0、出错返回-1.

对于文件,remove和unlink相同。对于目录,remove的功能与rmdir相同,用于删除一个空目录。不能删除非空目录!

2.3 rename函数

文件或目录用rename更名

#include <stdio.h>int rename(const char *oldname,const char *newname);                                                    成功返回0,失败返回-1.

当oldname是文件时:则为此文件或符号链接更名,如果newname已存在且不是引用一个目录,则删除该项,使oldname更名为newname。

当oldname是目录时:则为此目录更名,如果newname已经存在,且是一个空目录,则先将其删除,然后将oldname更名为newname。特别的,newname中不能使用oldname做为其前缀。

3 文件时间

对于每个文件,有三个与之相关的时间。存在与stat结构中。

          st_atime        文件数据的最后访问时间

          st_mtime          文件数据的最后修改时间

          st_ctime         i节点状态的最后更改时间

有许多操作更改文件的i节点状态:更改文件的访问权限、用户ID、链接数等。但并没有修改文件的实际内容。

系统不保存对i节点的最后访问时间,所以access和stat函数并不修改任何时间。

3.1 utime函数

一个文件的访问时间和修改时间可以用utime更改。

#include <utime.h>int utime(const char *pathname,struct utimbuf *times);                                                    成功返回0,出错返回-1.  

struct utimbuf{

  time_t  actime;    /* access time */

  time_t  modtime;   /* modification time */

};

此结构的时间是日历时间,即自1970以来的秒数。

如果times为NULL。则使用当前时间设置文件的对应时间,进程必须有相应的权限。

如果times不为空。则设置为相应的值。

特别得,我们不能更改st_ctime的值,调用utime时自动更新。

#include <stdio.h>#include <unistd.h>#include <fcntl.h>#include <sys/stat.h>#include <utime.h>int main(int argc,char *argv[]){    int i,fd;    struct stat statbuf;    struct utimbuf timebuf;    for(i = 1;i < argc;i++)    {        if(stat(argv[i],&statbuf) < 0 )            {                printf("stat error !\n");                continue;            }        if(open(argv[i],O_RDWR | O_TRUNC) < 0)        {            printf("open error!\n");            continue;        }        timebuf.actime = statbuf.st_atime;        timebuf.modtime = statbuf.st_mtime;        if(utime(argv[i],&timebuf) < 0)        {            printf("utime error!\n");            continue;        }    }    return 0;}

编译运行:

root@debian:/program# ls -l test.c-rw-r--r-- 1 debian debian 63 Nov  9 21:21 test.croot@debian:/program# ls -lu test.c-rw-r--r-- 1 debian debian 63 Nov 19 11:02 test.croot@debian:/program# ls -lc test.c-rw-r--r-- 1 debian debian 63 Nov  9 21:21 test.croot@debian:/program# dateWed Nov 19 20:12:42 CST 2014root@debian:/program# ./4-6 test.croot@debian:/program# ls -l test.c-rw-r--r-- 1 debian debian 0 Nov  9 21:21 test.croot@debian:/program# ls -lu test.c-rw-r--r-- 1 debian debian 0 Nov 19 11:02 test.croot@debian:/program# ls -lc test.c-rw-r--r-- 1 debian debian 0 Nov 19 20:12 test.croot@debian:/program# ^Croot@debian:/program# 

从上面的结构可以看到,当调用stat函数时,最后修改时间和最后访问时间都没有变。但是,更改状态时间为程序运行的时间。

 

unix环境高级编程笔记(5)—— 文件和目录(2)