文件的时间
Posted fireway
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了文件的时间相关的知识,希望对你有一定的参考价值。
文件的时间
引言
ls(1)命令按照文件的时间排序可以参考如下选项:
- 系统默认(用-l或者-t)是按照文件的修改时间的先后排序
- -u选项按访问时间排序
- -c选项按状态更改时间排序
其实就是按照stat结构体下面的3个时间值中的一个排序。
struct stat
{
mode_t st_mode; /* file type & mode (permissions) */
ino_t st_ino; /* i-node number (serial number) */
dev_t st_dev; /* device number (file system) */
dev_t st_rdev; /* device number for special files */
nlink_t st_nlink; /* number of links */
uid_t st_uid; /* user ID of owner */
gid_t st_gid; /* group ID of owner */
off_t st_size; /* size in bytes, for regular files */
struct timespec st_atim; /* time of last access */
struct timespec st_mtim; /* time of last modification */
struct timespec st_ctim; /* time of last file status change */
blksize_t st_blksize; /* best I/O block size */
blkcnt_t st_blocks; /* number of disk blocks allocated */
};
注意,stat结构中的大多数成员都是基本系统数据类型。
timespec结构类型如下,其定义在linux/time.h:
struct timespec {
time_t tv_sec; /* seconds */
long tv_nsec; /* nanoseconds */
};
在2008年版以前的标准中,时间字段定义成st_atime、st_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
一个文件的访问和修改时间可以用以下几个函数更改。futimens和utimensat函数可以指定纳秒级精度的时间戳。
#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
#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为格林尼治标准时间。
futimens和utimensat函数都包含在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参数指向包含两个时间戳(访问时间和修改时间)元素的数组,两个时间戳是用秒和微妙表示的。
struct timeval {
time_t tv_sec; /* seconds */
long tv_usec; /* microseconds */
};
注意,我们不能对状态变更时间st_ctim(i节点最近被修改的时间)指定一个值,因为调用utimes函数时,此字段会被自动更新。
在某些UNIX版本中,touch(1)命令使用这些函数中的某一个。
实例
使用带O_TRUNC选项的open函数将文件长度截断为0,但并不更改其访问时间。为了做到这点,首先使用stat函数得到这些时间,然后截断文件,最后再用futimens函数重置这两个时间。
/**
* 文件内容:使用带O_TRUNC选项的open函数将文件长度截断为0,但并不更改其访问时间
* 作者:[email protected]
* 时间:2016年 11月 04日 星期五 22:00:14 CST
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
int main(int argc, char *argv[])
{
int fd = 0;
struct stat statbuf;
struct timespec times[2];
int i = 0;
for (i = 1; i < argc; i++)
{
if (stat(argv[i], &statbuf) < 0)
{
printf("%s: stat error: %s\n", argv[1], strerror(errno));
continue;
}
if (fd = open(argv[i], O_RDWR | O_TRUNC) < 0)
{
printf("%s: open error: %s\n", argv[1], strerror(errno));
continue;
}
times[0] = statbuf.st_atim;
times[1] = statbuf.st_mtim;
if (futimens(fd, times) < 0)
{
printf("%s: futimens error: %s\n", argv[1], strerror(errno));
}
if (fd > 0)
{
close(fd);
}
}
exit(0);
}
代码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
以上是关于文件的时间的主要内容,如果未能解决你的问题,请参考以下文章
我在哪里更改此 Python 代码片段以将临时文件保存在 tmp 文件夹中?
在Tomcat的安装目录下conf目录下的server.xml文件中增加一个xml代码片段,该代码片段中每个属性的含义与用途