修改文件时间信息的函数futimens、utimensat和utimes

2024-04-06 21:38

本文主要是介绍修改文件时间信息的函数futimens、utimensat和utimes,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

 

#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);
两个函数返回值:若成功,返回0;若出错,返回-1

(1)如果times参数是一个空指针,则访问时间和修改时间两者都设置为当前时间。

以一个图片为例,在/home/zhihui/Pictures 路径下有一个文件:book.jpg

现将修改时间mtime,访问时间atime,i节点更改时间ctime 输出如下:

现修改这个文件的访问时间和修改时间

#include <stdio.h>
#include <sys/stat.h>
#include <fcntl.h>int main() {struct timespec time[2];int fd;fd = open("/home/zhihui/Pictures/book.jpg",O_RDONLY);if(fd == -1){printf("open file failed.\n");}else{if(-1 == futimens(fd,NULL)){printf("modify time failed.\n");}else{printf("modify time cucceed.\n");}}return 0;
}

由下图可见,当times参数空指针时,文件的访问时间,修改时间(包括i节点修改时间)都变为Nov  1  11:18 

 

(2)如果times参数指向两个timespec结构的数组,任一数组元素的tv_nsec字段的值为UTIME_NOW,相应的时间戳就设置为当前时间,忽略相应的tv_sec字段。

代码如下,我们仅将time[0]的tv_nsec设置为UTIME_NOW 其他成员采用系统默认值。

#include <stdio.h>
#include <sys/stat.h>
#include <fcntl.h>int main() {struct timespec time[2];time[0].tv_nsec = UTIME_NOW;int fd;fd = open("/home/zhihui/Pictures/book.jpg",O_RDONLY);if(fd == -1){printf("open file failed.\n");}else{if(-1 == futimens(fd,time)){printf("modify time failed.\n");}else{printf("modify time cucceed.\n");}}return 0;
}

运行后结果如下:

 $ ls -al | grep book
-rw-rw-r--  1 zhihui zhihui  26786 Feb 18  1970 book.jpg$ ls -al --time=atime | grep book
-rw-rw-r--  1 zhihui zhihui  26786 Nov  1 11:36 book.jpg$ ls -al --time=ctime | grep book
-rw-rw-r--  1 zhihui zhihui  26786 Nov  1 11:36 book.jpg

值得注意的一点是,文件的修改时间(mtime)变为了Feb 18 1970

只有atime和ctime变为了当前时间。

我们对上面的代码稍作修改

#include <stdio.h>
#include <sys/stat.h>
#include <fcntl.h>int main() {struct timespec time[2];time[0].tv_nsec = UTIME_NOW;time[1].tv_nsec = UTIME_NOW;int fd;fd = open("/home/zhihui/Pictures/book.jpg",O_RDONLY);if(fd == -1){printf("open file failed.\n");}else{if(-1 == futimens(fd,time)){printf("modify time failed.\n");}else{printf("modify time cucceed.\n");}}return 0;
}


 增加了

time[1].tv_nsec = UTIME_NOW;

因为第一个time的第一个元素包含访问时间,第二个元素包含修改时间。将两个时间都设置为UTIME_NOW

运行结果如下

$ ls -al | grep book
-rw-rw-r--  1 zhihui zhihui  26786 Nov  1 11:41 book.jpg$ ls -al --time=atime | grep book
-rw-rw-r--  1 zhihui zhihui  26786 Nov  1 11:41 book.jpg$ ls -al --time=ctime | grep book
-rw-rw-r--  1 zhihui zhihui  26786 Nov  1 11:41 book.jpg

可以看到,文件的mtime 也变成了当前时间。

再做一点修改,将time[0].tv_nsec = UTIME_NOW;这一行注释

#include <stdio.h>
#include <sys/stat.h>
#include <fcntl.h>int main() {struct timespec time[2];
//    time[0].tv_nsec = UTIME_NOW;time[1].tv_nsec = UTIME_NOW;int fd;fd = open("/home/zhihui/Pictures/book.jpg",O_RDONLY);if(fd == -1){printf("open file failed.\n");}else{if(-1 == futimens(fd,time)){printf("modify time failed.\n");}else{printf("modify time cucceed.\n");}}return 0;
}

 

 

运行结果如下

$ ls -al | grep book
-rw-rw-r--  1 zhihui zhihui  26786 Nov  1 11:46 book.jpg$ ls -al --time=atime | grep book
-rw-rw-r--  1 zhihui zhihui  26786 Dec  6  4461538 book.jpg$ ls -al --time=ctime | grep book
-rw-rw-r--  1 zhihui zhihui  26786 Nov  1 11:46 book.jpg

值得注意的是,atime 变成了Dec  6  4461538,由于访问时间未定义,因此呈现出来的时间格式也不正常。

现在再回过头来看这句话:如果times参数指向两个timespec结构的数组,任一数组元素的tv_nsec字段的值为UTIME_NOW,相应的时间戳就设置为当前时间,忽略相应的tv_sec字段。

也就是说,只将第一个数组元素的tv_nsec置为UTIME_NOW,则对应的访问时间就变成当前时间,只将第二个数组元素的tv_nsec置为UTIME_NOW,则对应的修改时间就变成当前时间。但是无论是那个元素的tv_nsec置为UTIME_NOW,文件的ctime即i节点修改时间都会变为当前时间。

(3)如果times参数指向两个timespec结构的数组,任一数组元素的tv_nsec字段的值为UTIME_OMIT,相应的时间戳保持不变,忽略相应的tv_sec字段。

我们读取文件a的访问时间和修改时间,并将这个时间存储到time结构体中.然后将文件b的时间状态设为当前时间,再用time结构体中保存的时间去设置文件b的访问时间和修改时间并将time结构体数组其中一个元素的tv_nsec设置为UTIME_OMIT。比如,在目录/home/zhihui/Pictures 下有文件 container.odg ,我们先从命令行查询这个文件的时间信息,得到如下信息:

 $ ls -al | grep container.odg 
-rw-rw-r--  1 zhihui zhihui 269171 Sep 12 09:24 container.odg$ ls -al --time=ctime | grep container.odg 
-rw-rw-r--  1 zhihui zhihui 269171 Sep 12 09:24 container.odg$ ls -al --time=atime -h  | grep container.odg 
-rw-rw-r--  1 zhihui zhihui 263K Sep 12 09:24 container.odg

编写如下代码 

#include <stdio.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>int main() {struct timespec time[2];struct stat buf[10];int fd;fd = open("/home/zhihui/Pictures/container.odg",O_RDONLY);fstat(fd,buf);close(fd);time[0] = buf[0].st_atim;time[1] = buf[0].st_mtim;time[1].tv_nsec = UTIME_OMIT;fd = open("/home/zhihui/Pictures/book.jpg",O_RDONLY);if(fd == -1){printf("open file failed.\n");}else{if(-1 == futimens(fd,NULL)){            //设为当前时间printf("modify time failed.\n");}else{printf("modify time cucceed.\n");}if(-1 == futimens(fd,time)){printf("modify time failed.\n");}else{printf("modify time cucceed.\n");}}close(fd);return 0;
}

执行结果如下:

$ ls -al | grep book
-rw-rw-r--  1 zhihui zhihui  26786 Nov  1 18:19 book.jpg$ ls -al --time=ctime | grep book
-rw-rw-r--  1 zhihui zhihui  26786 Nov  1 18:19 book.jpg$ ls -al --time=atime | grep book
-rw-rw-r--  1 zhihui zhihui  26786 Sep 12 09:24 book.jpg

我们将time0设置为了和container.odg的访问时间时间 Sep 12 09:24 ,time[0]改变的是文件的访问时间,所以我们看到atime 变为了Sep 12 09:24。另一方面time[1]的tv_nsec被设置为UTIME_OMIT,因此time[1]的tv_sec总的数据被忽略,因而文件的修改时间依然是当前时间。

(4)如果 times 参数指向两个 timespec 结构的数组,且 tv_nsec 字段的值为既不是UTIME_NOW 也不是 UTIME_OMIT,在这种情

况下,相应的时间戳设置为相应的 tv_sec 和tv_nsec字段的值。

我们使用和上面相同的方法。查询文件a的访问时间和修改时间,并将这个时间存储到time结构体中.然后将文件b的时间状态设为当前时间,再用time结构体中保存的时间去设置文件b的访问时间和修改时间

编写如下代码: 

#include <stdio.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>int main() {struct timespec time[2];struct stat buf[10];int fd;fd = open("/home/zhihui/Pictures/container.odg",O_RDONLY);fstat(fd,buf);close(fd);time[0] = buf[0].st_atim;time[1] = buf[0].st_mtim;fd = open("/home/zhihui/Pictures/book.jpg",O_RDONLY);if(fd == -1){printf("open file failed.\n");}else{if(-1 == futimens(fd,NULL)){            //设为当前时间printf("modify time failed.\n");}else{printf("modify time cucceed.\n");}if(-1 == futimens(fd,time)){printf("modify time failed.\n");}else{printf("modify time cucceed.\n");}}close(fd);return 0;
}

 

$ ls -al | grep book
-rw-rw-r--  1 zhihui zhihui  26786 Sep 12 09:24 book.jpg$ ls -al --time=ctime | grep book
-rw-rw-r--  1 zhihui zhihui  26786 Nov  1 18:36 book.jpg$ ls -al --time=atime | grep book
-rw-rw-r--  1 zhihui zhihui  26786 Sep 12 09:24 book.jpg

可以看到文件的读取时间和修改时间都已经改变。

 

utimes函数对路径名进行操作。times参数是指向包含两个时间戳(访问时间和修改时间)元素的数组的指针,两个时间戳是用秒和微妙表示的。

struct timeval {
time_t tv_sec; /* seconds */
long tv_usec; /* microseconds */
};
编写如下代码,将文件读取时间设置为1970年1月3号,文件修改时间设置为1970年1月4号:

#include <stdio.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/time.h>int main() {struct timeval time[2];time[0].tv_sec =  2 * 24*60*60 + 26 * 60;time[0].tv_usec = 0;time[1].tv_sec =  3 * 24*60*60 + 44 * 60;time[1].tv_usec = 0;if(-1 == utimes("/home/zhihui/Pictures/book.jpg",time)){printf("modify time failed.\n");}else{printf("modify time cucceed.\n");}return 0;
}

 运行结果如下:

$ ls -al | grep book
-rw-rw-r--  1 zhihui zhihui  26786 Jan  4  1970 book.jpg$ ls -al --time=ctime | grep book
-rw-rw-r--  1 zhihui zhihui  26786 Nov  1 19:40 book.jpg$ ls -al --time=atime | grep book
-rw-rw-r--  1 zhihui zhihui  26786 Jan  3  1970 book.jpg

 

这篇关于修改文件时间信息的函数futimens、utimensat和utimes的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


原文地址:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.chinasem.cn/article/880896

相关文章

Python函数返回多个值的多种方法小结

《Python函数返回多个值的多种方法小结》在Python中,函数通常用于封装一段代码,使其可以重复调用,有时,我们希望一个函数能够返回多个值,Python提供了几种不同的方法来实现这一点,需要的朋友... 目录一、使用元组(Tuple):二、使用列表(list)三、使用字典(Dictionary)四、 使

Linux查看系统盘和SSD盘的容量、型号及挂载信息的方法

《Linux查看系统盘和SSD盘的容量、型号及挂载信息的方法》在Linux系统中,管理磁盘设备和分区是日常运维工作的重要部分,而lsblk命令是一个强大的工具,它用于列出系统中的块设备(blockde... 目录1. 查看所有磁盘的物理信息方法 1:使用 lsblk(推荐)方法 2:使用 fdisk -l(

利用Python实现时间序列动量策略

《利用Python实现时间序列动量策略》时间序列动量策略作为量化交易领域中最为持久且被深入研究的策略类型之一,其核心理念相对简明:对于显示上升趋势的资产建立多头头寸,对于呈现下降趋势的资产建立空头头寸... 目录引言传统策略面临的风险管理挑战波动率调整机制:实现风险标准化策略实施的技术细节波动率调整的战略价

SpringBoot如何对密码等敏感信息进行脱敏处理

《SpringBoot如何对密码等敏感信息进行脱敏处理》这篇文章主要为大家详细介绍了SpringBoot对密码等敏感信息进行脱敏处理的几个常用方法,文中的示例代码讲解详细,感兴趣的小伙伴可以了解下... 目录​1. 配置文件敏感信息脱敏​​2. 日志脱敏​​3. API响应脱敏​​4. 其他注意事项​​总结

PyTorch中cdist和sum函数使用示例详解

《PyTorch中cdist和sum函数使用示例详解》torch.cdist是PyTorch中用于计算**两个张量之间的成对距离(pairwisedistance)**的函数,常用于点云处理、图神经网... 目录基本语法输出示例1. 简单的 2D 欧几里得距离2. 批量形式(3D Tensor)3. 使用不

Nginx 413修改上传文件大小限制的方法详解

《Nginx413修改上传文件大小限制的方法详解》在使用Nginx作为Web服务器时,有时会遇到客户端尝试上传大文件时返回​​413RequestEntityTooLarge​​... 目录1. 理解 ​​413 Request Entity Too Large​​ 错误2. 修改 Nginx 配置2.1

MySQL 字符串截取函数及用法详解

《MySQL字符串截取函数及用法详解》在MySQL中,字符串截取是常见的操作,主要用于从字符串中提取特定部分,MySQL提供了多种函数来实现这一功能,包括LEFT()、RIGHT()、SUBST... 目录mysql 字符串截取函数详解RIGHT(str, length):从右侧截取指定长度的字符SUBST

Python对PDF书签进行添加,修改提取和删除操作

《Python对PDF书签进行添加,修改提取和删除操作》PDF书签是PDF文件中的导航工具,通常包含一个标题和一个跳转位置,本教程将详细介绍如何使用Python对PDF文件中的书签进行操作... 目录简介使用工具python 向 PDF 添加书签添加书签添加嵌套书签Python 修改 PDF 书签Pytho

Python日期和时间完全指南与实战

《Python日期和时间完全指南与实战》在软件开发领域,‌日期时间处理‌是贯穿系统设计全生命周期的重要基础能力,本文将深入解析Python日期时间的‌七大核心模块‌,通过‌企业级代码案例‌揭示最佳实践... 目录一、背景与核心价值二、核心模块详解与实战2.1 datetime模块四剑客2.2 时区处理黄金法

macOS Sequoia 15.5 发布: 改进邮件和屏幕使用时间功能

《macOSSequoia15.5发布:改进邮件和屏幕使用时间功能》经过常规Beta测试后,新的macOSSequoia15.5现已公开发布,但重要的新功能将被保留到WWDC和... MACOS Sequoia 15.5 正式发布!本次更新为 Mac 用户带来了一系列功能强化、错误修复和安全性提升,进一步增