时间获取、文件属性获取 2月20日学习笔记

news2024/12/26 11:32:16

执行两次代码,打印出两次执行过程中新增的文件及删除的文件

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <dirent.h>

#define	RECORD_PATH		"record.bk"

int ListDir(const char *pdirname, FILE *file) //遍历指定目录下的所有文件和子目录,并将文件路径写入到指定的文件中
{
	DIR *dp = NULL;
	struct dirent *pp = NULL;
	char tmpbuff[1024] = {0};

	dp = opendir(pdirname);
	if (NULL == dp)
	{
		perror("fail to opendir");
		return -1;
	}

	while (1)
	{
		pp = readdir(dp);
		if (NULL == pp)
		{
			break;
		}

		if ('.' == pp->d_name[0])
		{
			continue;
		}

		sprintf(tmpbuff, "%s/%s", pdirname, pp->d_name);
		fprintf(file, "%s\n", tmpbuff);

		if (DT_DIR == pp->d_type)
		{
			ListDir(tmpbuff, file);
		}
	}

	closedir(dp);

	return 0;
}

int ListDirToRecord(const char *pdirname)//使用ListDir函数遍历指定目录,并将结果写入到名为record.bk的文件中。
{
	FILE *fp = NULL;

	fp = fopen(RECORD_PATH, "w");
	if (NULL == fp)
	{
		perror("fail to fopen");
		return -1;
	}

	ListDir(pdirname, fp);

	fclose(fp);

	return 0;
}

int ShowDeleteFiles(void)//打开record.bk文件,读取其中的文件路径,并判断这些文件是否存在于文件系统中。如果不存在,则打印这些文件路径,即表示这些文件已被删除
{
	FILE *fp = NULL;
	char tmpbuff[4096] = {0};
	char *pret = NULL;

	fp = fopen(RECORD_PATH, "r");
	if (NULL == fp)
	{
		perror("fail to fopen");
		return -1;
	}
	
	while (1)
	{
		pret = fgets(tmpbuff, sizeof(tmpbuff), fp);
		if (NULL == pret)
		{
			break;
		}

		tmpbuff[strlen(tmpbuff)-1] = '\0';

		if (access(tmpbuff, F_OK) != 0)
		{
			printf("%s\n", tmpbuff);
		}
	}

	fclose(fp);

	return 0;
}

int IsNewFile(char *pfilepath)//判断指定的文件路径是否在record.bk中存在。如果存在,则返回0,表示不是新文件;如果不存在,则返回1,表示是新文件
{
	FILE *fp = NULL;
	char tmpbuff[4096] = {0};
	char *pret = NULL;

	fp = fopen(RECORD_PATH, "r");
	if (NULL == fp)
	{
		perror("fail to fopen");
		return -1;
	}

	while (1)
	{
		pret = fgets(tmpbuff, sizeof(tmpbuff), fp);
		if (NULL == pret)
		{
			break;
		}

		tmpbuff[strlen(tmpbuff)-1] = '\0';
		
		if (0 == strcmp(tmpbuff, pfilepath))
		{
			fclose(fp);
			return 0;
		}
	}

	fclose(fp);

	return 1;
}

int ListDir2(const char *pdirname)//用于遍历指定目录下的所有文件和子目录,并判断每个文件路径是否为新文件(调用IsNewFile函数)。如果是新文件,则打印该文件路径。
{
	DIR *dp = NULL;
	struct dirent *pp = NULL;
	char tmpbuff[1024] = {0};

	dp = opendir(pdirname);
	if (NULL == dp)
	{
		perror("fail to opendir");
		return -1;
	}

	while (1)
	{
		pp = readdir(dp);
		if (NULL == pp)
		{
			break;
		}

		if ('.' == pp->d_name[0])
		{
			continue;
		}

		sprintf(tmpbuff, "%s/%s", pdirname, pp->d_name);
		if (IsNewFile(tmpbuff))
		{
			printf("%s\n", tmpbuff);
		}

		if (DT_DIR == pp->d_type)
		{
			ListDir2(tmpbuff);
		}
	}

	closedir(dp);

	return 0;
}

int ShowNewFiles(const char *pdirname)//调用ListDir2函数遍历指定目录,然后打印所有新文件的路径
{
	ListDir2(pdirname);

	return 0;
}

int main(void)//首先检查是否存在record.bk文件,如果存在,则调用ShowDeleteFiles函数打印已删除的文件路径,然后调用ShowNewFiles函数打印新增的文件路径。如果record.bk文件不存在,则调用ListDirToRecord函数生成该文件
{
	int ret = 0;

	ret = access(RECORD_PATH, F_OK);
	if (0 == ret)
	{
		printf("删除的文件:\n");
		ShowDeleteFiles();	
		printf("新增的文件:\n");
		ShowNewFiles(".");
	}
	else 
	{
		ListDirToRecord(".");
	}

	return 0;
}

  一、时间获取

1.time 


      time_t time(time_t *tloc);
      功能:
        返回1970-1-1到现在的秒数(格林威治时间)
      参数:
        tloc:存放秒数空间首地址
      返回值:
        成功返回秒数
        失败返回-1 

 2.localtime


      struct tm *localtime(const time_t *timep);
      功能:
        将秒数转换为本地时间
      参数:
        timep:存放秒数空间首地址
      返回值:
        成功返回结构体时间
        失败返回NULL

        struct tm {
            int tm_sec;    /* Seconds (0-60) */
            int tm_min;    /* Minutes (0-59) */
            int tm_hour;   /* Hours (0-23) */
            int tm_mday;   /* Day of the month (1-31) */
            int tm_mon;    /* Month (0-11) */
            int tm_year;   /* Year - 1900 */
            int tm_wday;   /* Day of the week (0-6, Sunday = 0) */
            int tm_yday;   /* Day in the year (0-365, 1 Jan = 0) */
            int tm_isdst;  /* Daylight saving time */
        };

    3.mktime


      time_t mktime(struct tm *tm);
      功能:
        将本地时间转换为秒数

获取前一天的日期和时间

#include "head.h"

int main(void)
{	
	time_t t;
	struct tm *ptm = NULL;
	struct tm tmp;

	tmp.tm_year = 2024-1900;
	tmp.tm_mon = 2-1;
	tmp.tm_mday = 20;
	tmp.tm_hour = 11;
	tmp.tm_min = 22;
	tmp.tm_sec = 30;
	t = mktime(&tmp);
	t -= 86400; //。通过 t -= 86400 对时间值进行减去一天的秒数的操作。

//	time(&t);

	ptm = localtime(&t);
	printf("%04d-%02d-%02d %02d:%02d:%02d\n", ptm->tm_year+1900, ptm->tm_mon+1, ptm->tm_mday, ptm->tm_hour, ptm->tm_min, ptm->tm_sec);
	

	return 0;
}

二、文件属性和权限的获取:

1.stat


      int stat(const char *pathname, struct stat *statbuf);
      功能:
        将pathname对应的文件信息放入statbuf中
      参数:
        pathname:文件路径字符串的首地址
        statbuf:存放文件信息空间的首地址
      返回值:
        成功返回0 
        失败返回-1 

    struct stat {
        dev_t     st_dev;         /* ID of device containing file */
        ino_t     st_ino;         /* Inode number */
        mode_t    st_mode;        /* File type and mode */
        nlink_t   st_nlink;       /* Number of hard links */
        uid_t     st_uid;         /* User ID of owner */
        gid_t     st_gid;         /* Group ID of owner */
        dev_t     st_rdev;        /* Device ID (if special file) */
        off_t     st_size;        /* Total size, in bytes */
        blksize_t st_blksize;     /* Block size for filesystem I/O */
        blkcnt_t  st_blocks;      /* Number of 512B blocks allocated */

        /* Since Linux 2.6, the kernel supports nanosecond
            precision for the following timestamp fields.
            For the details before Linux 2.6, see NOTES. */

        struct timespec st_atim;  /* Time of last access */
        struct timespec st_mtim;  /* Time of last modification */
        struct timespec st_ctim;  /* Time of last status change */

    #define st_atime st_atim.tv_sec      /* Backward compatibility */
    #define st_mtime st_mtim.tv_sec
    #define st_ctime st_ctim.tv_sec
    };

    /etc/passwd   口令文件
    /etc/group    组信息文件

    2.getpwuid 


      struct passwd *getpwuid(uid_t uid);
      功能:
        通过UID获得对应的用户信息
      参数:
        uid:用户的ID号
      返回值:
        成功返回包含用户信息的结构体
        失败返回NULL

    struct passwd {
        char   *pw_name;       /* username */
        char   *pw_passwd;     /* user password */
        uid_t   pw_uid;        /* user ID */
        gid_t   pw_gid;        /* group ID */
        char   *pw_gecos;      /* user information */
        char   *pw_dir;        /* home directory */
        char   *pw_shell;      /* shell program */
    };

    3.getgrgid


      struct group *getgrgid(gid_t gid);
      功能:
        通过组ID获得组信息
      参数:
        gid:组的ID号
      返回值:
        成功返回包含组信息的结构体
        失败返回NULL
    
    struct group {
        char   *gr_name;        /* group name */
        char   *gr_passwd;      /* group password */
        gid_t   gr_gid;         /* group ID */
        char  **gr_mem;         /* NULL-terminated array of pointers
                                    to names of group members */
    };

    4.readlink


      ssize_t readlink(const char *pathname, char *buf, size_t bufsiz);
      功能:
        读取连接文件本身的内容
      参数:
        pathname:链接文件的路径
        buf:存放数据空间首地址
        bufsiz:最大存放数据字节数
      返回值:
        成功返回读到字节个数
        失败返回-1 

获取给定文件的详细信息,并以类似 ls -l 命令的格式进行输出

#include "head.h"

int main(int argc, const char *argv[])
{
	struct stat buf;
	int ret = 0;
	struct passwd *pwd = NULL;
	struct group *grp = NULL;
	struct tm *ptm = NULL;
	char *mon[12] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
	char tmpbuff[1024] = {0};

	if (argc != 2)
	{
		fprintf(stderr, "Usage:./a.out filename\n");
		return -1;
	}

	ret = lstat(argv[1], &buf);
	if (-1 == ret)
	{
		perror("fail to stat");
		return -1;
	}

#if 0
	switch (buf.st_mode & S_IFMT)
	{
		case S_IFDIR:putchar('d');break;
		case S_IFREG:putchar('-');break;
		case S_IFSOCK:putchar('s');break;
		case S_IFLNK:putchar('l');break;
		case S_IFBLK:putchar('b');break;
		case S_IFCHR:putchar('c');break;
		case S_IFIFO:putchar('p');break;
	}
#endif

	if (S_ISREG(buf.st_mode))
	{
		putchar('-');
	}
	else if (S_ISDIR(buf.st_mode))
	{
		putchar('d');	
	}
	else if (S_ISCHR(buf.st_mode))
	{
		putchar('c');
	}
	else if (S_ISBLK(buf.st_mode))
	{
		putchar('b');
	}
	else if (S_ISLNK(buf.st_mode))
	{
		putchar('l');
	}
	else if (S_ISSOCK(buf.st_mode))
	{
		putchar('s');
	}
	else if (S_ISFIFO(buf.st_mode))
	{
		putchar('p');
	}
	
	buf.st_mode & S_IRUSR ? putchar('r') : putchar('-');
	buf.st_mode & S_IWUSR ? putchar('w') : putchar('-');
	buf.st_mode & S_IXUSR ? putchar('x') : putchar('-');

	buf.st_mode & S_IRGRP ? putchar('r') : putchar('-');
	buf.st_mode & S_IWGRP ? putchar('w') : putchar('-');
	buf.st_mode & S_IXGRP ? putchar('x') : putchar('-');

	buf.st_mode & S_IROTH ? putchar('r') : putchar('-');
	buf.st_mode & S_IWOTH ? putchar('w') : putchar('-');
	buf.st_mode & S_IXOTH ? putchar('x') : putchar('-');

	printf(" %ld", buf.st_nlink);
	
	pwd = getpwuid(buf.st_uid);
	if (NULL == pwd)
	{
		printf(" %d", buf.st_uid);
	}
	else 
	{
		printf(" %s", pwd->pw_name);
	}
	
	grp = getgrgid(buf.st_gid);
	if (NULL == grp)
	{
		printf(" %d", buf.st_gid);
	}
	else 
	{
		printf(" %s", grp->gr_name);
	}
	
	printf(" %ld", buf.st_size);
	
	ptm = localtime(&buf.st_mtime);
	printf(" %s %d %d:%d", mon[ptm->tm_mon], ptm->tm_mday, ptm->tm_hour, ptm->tm_min);
	
	printf(" %s", argv[1]);

	if (S_ISLNK(buf.st_mode))
	{
		readlink(argv[1], tmpbuff, sizeof(tmpbuff));
		printf(" -> %s", tmpbuff);
	}

	putchar('\n');

	return 0;
}


三、软连接和硬链接:


    1.软连接(符号链接)


        通过文件名链接,所有能够看到的连接文件均为软连接文件

        ln -s file.txt a.txt 

软链接(符号链接):

  • 软链接是通过文件名链接,创建一个指向目标文件的链接。
  • 软链接文件本身只包含目标文件的路径名,而不是目标文件的实际数据。
  • 所有能够看到的连接文件都是软链接。
  • 当删除原始文件时,软链接仍然存在,但指向的目标文件将不再可用。
  • 创建软链接使用 ln -s 命令,例如:ln -s file.txt a.txt

    2.硬链接


        通过文件对应的inode节点链接     

        ln file.txt b.txt 

硬链接:

  • 硬链接是通过文件对应的 inode 节点链接,为同一个文件分配多个文件名。
  • 硬链接文件和原始文件具有相同的 inode 节点和相同的索引节点号。
  • 修改任何一个硬链接文件(如更改文件的内容),都会影响到其他硬链接文件。
  • 可以通过不同的文件名访问同一个文件的内容。
  • 当删除一个硬链接文件时,原始文件和其他硬链接文件仍然存在。
  • 创建硬链接使用 ln 命令,例如:ln file.txt b.txt

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Redis篇----第十一篇

系列文章目录 文章目录 系列文章目录前言一、Redis 如何做内存优化?二、Redis 回收进程如何工作的?三、都有哪些办法可以降低 Redis 的内存使用情况呢?四、Redis 的内存用完了会发生什么?前言 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下…

LabVIEW风力机智能叶片控制系统

​LabVIEW风力机智能叶片控制系统 介绍了一种风力机智能叶片控制系统的开发。通过利用LabVIEW软件与CDS技术&#xff0c;该系统能够实时监测并调整风力机叶片的角度&#xff0c;优化风能转换效率。此项技术不仅提高了风力发电的稳定性和效率&#xff0c;而且为风力机的智能化管…

Pandas时间序列数据补全

一、问题 时间序列数据缺失&#xff0c;将其补全。 如下图所示&#xff0c;数据存在缺失秒级的情况 二、方法 1、需要将时间戳字段设置成 df 的索引 2、使用df.resample()方法 (1)上采样&#xff08;将上一条数据作为当前缺失数据&#xff09; resample()中的参数&#x…

内核移植学习

内核移植 内核移植就是指将RT-Thread内核在不同的芯片架构、不同的板卡上运行起来。 移植可分为CPU架构移植和BSP板级支持包移植两部分。 CPU架构移植 在嵌入式领域有多种不同CPU架构&#xff0c;例如Cortex-M、ARM920T、MIPS32、RISC-V等等。 为了使RT-Thread能够在不同C…

【软件架构】01-架构的概述

1、定义 软件架构就是软件的顶层结构 RUP&#xff08;统一过程开发&#xff09;4 1 视图 1&#xff09;逻辑视图&#xff1a; 描述系统的功能、组件和它们之间的关系。它主要关注系统的静态结构&#xff0c;包括类、接口、包、模块等&#xff0c;并用于表示系统的组织结构…

Android基础Adapter适配器详解

一、概念 Adapter是后端数据和前端显示UI的适配器接口。常见的View如ListView、GridView等需要用到Adapter. BaseAdapter&#xff1a;抽象类&#xff0c;实际开发中继承这个类并且重写相关方法&#xff0c;用得最多的一个Adapter&#xff01; ArrayAdapter&#xff1a;支持泛型…

Gradle统一管理依赖

背景 随着项目越来越大&#xff0c;module 越来越多&#xff0c;依赖的库也越来越多&#xff0c;依赖管理也越来越混乱。 我们一般会有以下需求&#xff1a; 1. 项目依赖统一管理&#xff0c;在单独文件中配置 2. 不同 Module 中的依赖版本号统一 管理 Gradle 依赖 说明&a…

Vue3学习——标签的ref属性

在HTML标签上&#xff0c;可以使用相同的ref名称&#xff0c;得到DOM元素ref放在组件上时&#xff0c;拿到的是组件实例&#xff08;组件defineExpose暴露谁&#xff0c;ref才可以看到谁&#xff09; <script setup lang"ts"> import RefPractice from /compo…

C++/C函数指针及函数指针数组

文章目录 什么是函数指针函数指针的使用为什么要使用函数指针&#xff1f;回调函数函数指针数组及使用阅读两段有趣的代码指向成员函数的指针&#xff08;C特有&#xff09; 什么是函数指针 首先它是一个指针&#xff0c;一个指向函数的指针&#xff0c;在内存空间中存放的是函…

Camunda快速入门(五):设计一个带DMN业务规则的流程

接上一篇文章&#xff1a;Camunda快速入门&#xff08;四&#xff09;&#xff1a;设计一个带网关的流程 在本节中&#xff0c;您将学习如何使用 BPMN 2.0 业务规则任务和 DMN 1.3 决策表将决策自动化添加到流程中。 1、将业务规则任务添加到流程 使用 Camunda Modeler 打开…

Python学习-if else及比较运算符、while循环结构、random生成随机数模块

五、if else及比较运算符 1、if else语法 if 条件&#xff1a; 如果条件为真&#xff08;Ture&#xff09;执行这里的语句 else: 如果条件为假&#xff08;False&#xff09;执行这里的语句 2、比较运算符 运算符含义<判断左边是否小于右边<判断左边是否小于或等于右…

《nvm 安装》nodejs 版本管理工具

一.前言 如果先于 nvm 安装了 node&#xff0c;一定要先卸载&#xff01; 两种卸载方式&#xff1a; 方式一 控制面板 -> 程序和功能 -> nodejs 删除 方式二 下载的 node 安装包有卸载选项 二. 安装 nvm 下载地址 中找到对应的安装包&#xff0c;我本机使用 window…

关于公司私有gitlab拉去项目中遇到的问题

新进公司都会遇到拉去项目代码问题&#xff0c;新账号新环境&#xff1b;怎么拉去代码才是最有效的呢&#xff1f; 在此某些大神会给你一个地址&#xff1a;一句你自己来取吧&#xff1b;拉下来看看逻辑就行了&#xff1b;这样的人挺不错&#xff1b;会让你陷入无限的BUG循环中…

安卓adb调试备忘录

由于 MAC 的 USB 口全被占用着&#xff0c;采用无线连接刚方便&#xff0c;记录一下&#xff0c;以防忘记~ ADB原理 adb devices -l ## 列出连接的设备adb tcpip [端口号] adb tcpip 6666 # 将当前已连接USB上的Mobile端切换为TCP/IP模式&#xff0c;以6666端口进行监听. adb…

数字孪生与智慧城市:共筑未来城市的科技基石

一、引言 随着科技的飞速发展&#xff0c;数字孪生与智慧城市已成为未来城市建设的两大关键技术。数字孪生为城市提供了一个虚拟的数字镜像&#xff0c;使我们能全面、深入地了解城市的运行状态。而智慧城市则借助先进的信息通信技术&#xff0c;提升城市的智能化水平&#xf…

机器学习基础(三)监督学习的进阶探索

导语&#xff1a;上一节我们深入地探讨监督学习和非监督学习的知识&#xff0c;重点关注它们的理论基础、常用算法及实际应用场景&#xff0c;详情可见&#xff1a; 机器学习基础&#xff08;二&#xff09;监督与非监督学习-CSDN博客文章浏览阅读769次&#xff0c;点赞15次&a…

明御运维审计与风险控制系统漏洞复现

简介 明御运维审计与风险控制系统是安恒信息在多年运维安全管理的理论和实践经验积累的基础上,采用B/S架构,集“身份认证、账户管理、控制权限、日志审计”于一体,支持多种字符终端协议、文件传输协议、图形终端协议、远程应用协议的安全监控与历史查询,具备全方位运维风险…

springboot+vue的飘香水果购物网站(前后端分离)

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、阿里云专家博主、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战&#xff0c;欢迎高校老师\讲师\同行交流合作 ​主要内容&#xff1a;毕业设计(Javaweb项目|小程序|Pyt…

JavaScript 设计模式之组合模式

组合模式 在我们日常中肯呢个会将一个表单用这种模式来创建 const Car function () { } Car.prototype.getName function () { throw new Error("需要重写该方法") } Car.prototype.getPrice function () {throw new Error("需要重写该方法") } const…

05_i2c_controller内核模块

01_basicLinux内核模块-CSDN博客文章浏览阅读304次&#xff0c;点赞3次&#xff0c;收藏3次。环境IDubuntuMakefilemodules:clean:basic.creturn 0;运行效果。https://blog.csdn.net/m0_37132481/article/details/136157384i2c_controller.c rootT:/media/sf_D_DRIVE/kmodule/…