zoukankan      html  css  js  c++  java
  • 文件的时间

    文件的时间

    引言 

        ls(1)命令按照文件的时间排序可以参考如下选项:
    • 系统默认(用-l或者-t)是按照文件的修改时间的先后排序
    • -u选项按访问时间排序
    • -c选项按状态更改时间排序
        其实就是按照stat结构体下面的3个时间值中的一个排序。
    1. struct stat
    2. {
    3. mode_t st_mode;/* file type & mode (permissions) */
    4. ino_t st_ino;/* i-node number (serial number) */
    5. dev_t st_dev;/* device number (file system) */
    6. dev_t st_rdev;/* device number for special files */
    7. nlink_t st_nlink;/* number of links */
    8. uid_t st_uid;/* user ID of owner */
    9. gid_t st_gid;/* group ID of owner */
    10. off_t st_size;/* size in bytes, for regular files */
    11. struct timespec st_atim;/* time of last access */
    12. struct timespec st_mtim;/* time of last modification */
    13. struct timespec st_ctim;/* time of last file status change */
    14. blksize_t st_blksize;/* best I/O block size */
    15. blkcnt_t st_blocks;/* number of disk blocks allocated */
    16. };
        注意,stat结构中的大多数成员都是基本系统数据类型。
        timespec结构类型如下,其定义在linux/time.h
    1. struct timespec {
    2. time_t tv_sec;/* seconds */
    3. long tv_nsec;/* nanoseconds */
    4. };
        在2008年版以前的标准中,时间字段定义成st_atimest_mtime以及st_ctime,它们都是time_t类型(以秒来表示)。而之后timespec结构提供了更精度的时间戳。为了保持兼容性,旧的名字可以定义成tv_sec成员。例如,st_atime可以定义成st_atim.tv_sev。(注意少了一个e字母)
    Field Description Example ls(1) option
    st_atim last-access time of file data read -u
    st_mtim last-modification time of file data write 默认
    st_ctim last-change time of i-node status chmod、chown -c
    表1 与每个文件相关的3个时间值
        修改时间(st_mtim)是文件内容最后一次被修改的时间。
        状态更改时间(st_ctim)是该文件的i节点最后一次被修改的时间。
       

    函数futimens、utimensat和utimes

        一个文件的访问和修改时间可以用以下几个函数更改。futimensutimensat函数可以指定纳秒级精度的时间戳。
    #include <sys/stat.h>

    int futimens(int fd, const struct timespec times[2]);

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

    Both return: 0 if OK, −1 on error
        times数组参数的第一个元素包含访问时间,第二个元素包含修改时间。这两个时间值是日历时间。该值是自协调世界(Coordinated Universal Time, UTC)1970年1月1日00:00:00这个特定的时间以来所经过的秒数累计值。早期的手册称UTC为格林尼治标准时间。
        futimensutimensat函数都包含在POSIX.1中,而下面的utimes函数是在Single UNIX Specification的XSI扩展选项中。
    #include <sys/time.h>

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

    Returns: 0 if OK, −1 on error
         utimes函数对路径名进行操作。times参数指向包含两个时间戳(访问时间和修改时间)元素的数组,两个时间戳是用秒和微妙表示的。
    1. struct timeval {
    2. time_t tv_sec;/* seconds */
    3. long tv_usec;/* microseconds */
    4. };
        注意,我们不能对状态变更时间st_ctim(i节点最近被修改的时间)指定一个值,因为调用utimes函数时,此字段会被自动更新。
        在某些UNIX版本中,touch(1)命令使用这些函数中的某一个。

    实例

        使用带O_TRUNC选项的open函数将文件长度截断为0,但并不更改其访问时间。为了做到这点,首先使用stat函数得到这些时间,然后截断文件,最后再用futimens函数重置这两个时间。
     
    1. /**
    2. * 文件内容:使用带O_TRUNC选项的open函数将文件长度截断为0,但并不更改其访问时间
    3. * 作者:firewaywei@126.com
    4. * 时间:2016年 11月 04日 星期五 22:00:14 CST
    5. */
    6. #include<stdio.h>
    7. #include<stdlib.h>
    8. #include<string.h>
    9. #include<errno.h>
    10. #include<sys/types.h>
    11. #include<sys/stat.h>
    12. #include<unistd.h>
    13. #include<fcntl.h>
    14. int main(int argc,char*argv[])
    15. {
    16. int fd =0;
    17. struct stat statbuf;
    18. struct timespec times[2];
    19. int i =0;
    20. for(i =1; i < argc; i++)
    21. {
    22. if(stat(argv[i],&statbuf)<0)
    23. {
    24. printf("%s: stat error: %s ", argv[1], strerror(errno));
    25. continue;
    26. }
    27. if(fd = open(argv[i], O_RDWR | O_TRUNC)<0)
    28. {
    29. printf("%s: open error: %s ", argv[1], strerror(errno));
    30. continue;
    31. }
    32. times[0]= statbuf.st_atim;
    33. times[1]= statbuf.st_mtim;
    34. if(futimens(fd, times)<0)
    35. {
    36. printf("%s: futimens error: %s ", argv[1], strerror(errno));
    37. }
    38. if(fd >0)
    39. {
    40. close(fd);
    41. }
    42. }
    43. exit(0);
    44. }
    代码1 futimens函数实例
        程序运行如下:
    $ ls -l test test.c    <------------ 查看长度和最后修改时间
    -rwxrwxr-x 1 fireway fireway 9813  8月 14 18:14 test
    -rw-rw-r-- 1 fireway fireway  475  8月 14 18:04 test.c
    $ ls -lu test test.c    <-------------查看最后访问时间
    -rwxrwxr-x 1 fireway fireway 9813  8月 14 18:14 test
    -rw-rw-r-- 1 fireway fireway  475  9月  9 22:44 test.c
    $ date    <---------------打印当天日期
    2016年 11月 03日 星期四 07:54:21 CST
    $ a.out test test.c    <----------运行上面的程序
    $ ls -l test test.c    <--------------检查结果
    -rwxrwxr-x 1 fireway fireway 0 11月  3 07:55 test
    -rw-rw-r-- 1 fireway fireway 0 11月  3 07:55 test.c
    $ ls -lu test test.c    <----------------检查最后访问时间
    -rwxrwxr-x 1 fireway fireway 0  8月 14 18:14 test
    -rw-rw-r-- 1 fireway fireway 0  9月  9 22:44 test.c
    $ ls -lc test test.c    <-------------- 检查状态更改时间
    -rwxrwxr-x 1 fireway fireway 0 11月  3 07:55 test
    -rw-rw-r-- 1 fireway fireway 0 11月  3 07:55 test.c
        最后的访问时间没有修改,而修改时间和状态更改的时间则变更为程序运行的时间。

    参考

    UNIX环境高级编程(第三版)    4.20 函数futimens、utimensat和utimes
     
  • 相关阅读:
    Haskell Interactive Development in Emacs
    Access Java API in Groovy Script
    手工设置Eclipse文本编辑器的配色
    Color Theme of Emacs
    Gnucash的投资记录
    Special Forms and Syntax Sugars in Clojure
    Use w3m as Web Browser
    SSE指令集加速之 I420转BGR24
    【图像处理】 增加程序速度的方法
    TBB 入门笔记
  • 原文地址:https://www.cnblogs.com/fireway/p/6034263.html
Copyright © 2011-2022 走看看