C/C++实现重置文件时间戳
作者:lyshark
1.切割文件名与路径
如下代码是一段文件路径切割实现,通过传入文件路径,获取文件名和文件路径的功能。具体实现包括两个函数:GetFileName
和GetFilePath
。前者接收一个文件路径字符串,并返回该文件路径中的文件名;后者接收一个文件路径字符串,并返回该文件路径中除文件名以外的部分,即文件路径。
在main
函数中,首先定义了两个文件路径字符串szPathA
和szPathB
。然后,分别调用GetFileName
和GetFilePath
函数,将它们的返回值保存在指针变量ptr
中,并输出到控制台上。最后,程序返回0,结束执行。
#include <iostream> #include <Windows.h> #include <string.h> // 传入路径得到文件名 char* GetFileName(char* Path) { if (strchr(Path, '\\')) { char ch = '\\'; char* ref = strrchr(Path, ch) + 1; return ref; } else { char ch = '/'; char* ref = strrchr(Path, ch) + 1; return ref; } } // 传入路径只得到文件路径 char* GetFilePath(char *Path) { int i, pos; for (int count = 0; count < strlen(Path); count++) { if (Path[count] == '\\' || Path[count] == '/') { pos = count; } } Path[pos] = '\0'; return Path; } int main(int argc,char *argv[]) { char szPathA[128] = "C://Windows/LanguageOverlayCache/server.cpp"; char szPathB[128] = "c:\\Windows\\LanguageOverlayCache\\kernel.dll"; char* ptr = NULL; ptr = GetFileName(szPathA); std::cout << "文件名A: " << ptr << std::endl; ptr = GetFileName(szPathB); std::cout << "文件名B: " << ptr << std::endl; ptr = GetFilePath(szPathB); std::cout << "文件路径: " << ptr << std::endl; return 0; }
传入一个完整文件路径,并自动分割;
2.遍历目录下文件
如下代码是一个使用递归遍历目录,并输出指定格式的文件信息的程序。主要用到了文件操作函数findfirst()
、_findnext()
和_findclose()
,以及结构体类型_finddata_t
。
findfirst函数是Windows
平台上用于查找文件的函数之一,它属于 C Runtime Library(CRT)
中的一部分,提供了一种在指定目录中搜索文件的机制。
定义:
intptr_t _findfirst( const char *filespec, struct _finddata_t *fileinfo );
参数:
- filespec:指定要搜索的文件规范(通配符模式),可以包含路径信息。
- fileinfo:指向 finddata_t 结构的指针,用于存储找到的文件信息。
返回值:
如果成功,返回一个查找句柄(handle);如果失败,返回 -1。
findnext函数是Windows
平台上用于查找文件的函数之一,它通常与_findfirst
配合使用,用于获取指定目录中的下一个文件。
定义:
int _findnext( intptr_t handle, struct _finddata_t *fileinfo );
参数:
- handle:由
findfirst
返回的查找句柄。 - fileinfo:指向
finddata_t
结构的指针,用于存储找到的下一个文件的信息。
返回值:
如果成功,返回 0;如果失败或到达目录尾部,返回 -1。
函数dfsFolder()
分别接收目录路径和需要查找的文件格式。通过使用_findfirst()
找到该路径下的第一个文件或文件夹,如果是文件夹,则递归调用dfsFolder()
函数,如果是文件,则判断其是否为需要查找的格式,如果是则输出该文件的相关信息。
函数dfsFolderAll()
只传入了一个参数,即目录路径。该函数使用了和dfsFolder()
类似的方法,但是不判断文件格式,而是将该路径下的所有文件和文件夹都列出来,在main()
函数中,可以通过调用这两个函数来实现列出目录下所有文件和文件夹,或是列出目录下所有指定格式的文件。
#include <io.h> #include <iostream> using namespace std; // 列举出所有文件路径 void dfsFolderAll(string folderPath) { _finddata_t file; int k; long HANDLE; k = HANDLE = _findfirst(folderPath.c_str(), &file); while (k != -1) { cout << file.name << endl; k = _findnext(HANDLE, &file); } _findclose(HANDLE); } // 传入目录与需要列出的指定格式文件 void dfsFolder(string folderPath,string subpath) { _finddata_t FileInfo; /* 文件信息结构体 struct _finddata_t{ unsigned attrib; // 文件属性 time_t time_create; // 创建时的时间戳 time_t time_access; // 最后一次被访问时的时间戳 time_t time_write; // 最后一次被修改时的时间戳 _fsize_t size; // 文件字节大小 char name[_MAX_FNAME]; // 文件名 };*/ string strfind = folderPath + "\\*"; long Handle = _findfirst(strfind.c_str(), &FileInfo); if (Handle == -1L) { exit(0); } do { // 判断是否为目录 if (FileInfo.attrib & _A_SUBDIR) { // 判断目录是否为当前目录和上一级目录 if ((strcmp(FileInfo.name, ".") != 0) && (strcmp(FileInfo.name, "..") != 0)) { // 如果不是则拼接当前路径继续递归调用 string newPath = folderPath + "\\" + FileInfo.name; dfsFolder(newPath,subpath.c_str()); } } else { // 判断是不是指定后缀的文件 if (strstr(FileInfo.name, subpath.c_str())) { cout << " 文件名: " << FileInfo.name << " 文件大小: " << FileInfo.size; if (FileInfo.attrib == _A_NORMAL) { cout << " 普通文件 " << endl; } else if (FileInfo.attrib == _A_RDONLY) { cout << " 只读文件 " << endl; } else if (FileInfo.attrib == _A_HIDDEN) { cout << " 隐藏文件 " << endl; } else if (FileInfo.attrib == _A_SYSTEM) { cout << " 系统文件 " << endl; } else if (FileInfo.attrib == _A_SUBDIR) { cout << " 子目录 " << endl; } else { cout << " 存档文件 " << endl; } } } } while (_findnext(Handle, &FileInfo) == 0); _findclose(Handle); } int main(int argc,char *argv[]) { //dfsFolder("C:\\Windows\\system32",".dll"); dfsFolderAll("C:\\Windows\\system32\\*"); return 0; }
运行后输出所有C:\\Windows\\system32\\*
目录下的文件;
3.重置文件目录时间戳
文件目录时间戳是指与文件或目录相关联的时间信息,通常包括三个主要的时间戳:
- 创建时间(Creation Time): 表示文件或目录被创建的时间。这个时间戳记录了文件或目录在文件系统中第一次被创建的时间点。
- 最后访问时间(Last Access Time): 表示文件或目录最后一次被访问的时间。每当文件或目录被打开、读取、执行等操作时,最后访问时间都会更新。
- 最后修改时间(Last Write Time): 表示文件或目录最后一次被修改的时间。当文件内容发生变化、文件被写入时,最后修改时间会更新。
这些时间戳提供了关于文件或目录的重要信息,对于文件管理和调查文件活动非常有用。在Windows和许多其他操作系统中,这些时间戳通常以 FILETIME 结构体的形式存储,该结构体表示从1601年1月1日午夜开始计算的100纳秒间隔数。
这些时间戳可以通过文件系统或相关的系统调用函数(如 GetFileTime、SetFileTime)来访问和修改。
SystemTimeToFileTime 用于将SYSTEMTIME
结构体表示的时间转换为FILETIME
结构体表示的时间。
函数签名:
BOOL SystemTimeToFileTime( const SYSTEMTIME *lpSystemTime, LPFILETIME lpFileTime );
参数:
- lpSystemTime:指向 SYSTEMTIME 结构体的指针,表示待转换的系统时间。
- lpFileTime:指向 FILETIME 结构体的指针,用于存储转换后的文件时间。
返回值:
如果函数成功,返回非零值;如果函数失败,返回零。可以通过调用 GetLastError 函数获取更多信息。
LocalFileTimeToFileTime 用于将本地时间(FILETIME 结构体表示)转换为协调世界时(UTC)时间(同样是 FILETIME 结构体表示)。
函数签名:
BOOL LocalFileTimeToFileTime( const FILETIME *lpLocalFileTime, LPFILETIME lpFileTime );
参数:
- lpLocalFileTime:指向 FILETIME 结构体的指针,表示待转换的本地时间。
- lpFileTime:指向 FILETIME 结构体的指针,用于存储转换后的 UTC 时间。
返回值:
如果函数成功,返回非零值;如果函数失败,返回零。可以通过调用 GetLastError 函数获取更多信息。
SetFileTime 用于设置指定文件的创建时间、访问时间和修改时间。
函数签名:
BOOL SetFileTime( HANDLE hFile, const FILETIME *lpCreationTime, const FILETIME *lpLastAccessTime, const FILETIME *lpLastWriteTime );
参数:
- hFile:要设置时间信息的文件的句柄。
- lpCreationTime:指向 FILETIME 结构体的指针,表示文件的创建时间。
- lpLastAccessTime:指向 FILETIME 结构体的指针,表示文件的最后访问时间。
- lpLastWriteTime:指向 FILETIME 结构体的指针,表示文件的最后修改时间。
返回值:
如果函数成功,返回非零值;如果函数失败,返回零。可以通过调用 GetLastError 函数获取更多信息。
#include <io.h> #include <iostream> #include <windows.h> using namespace std; // 修改文件当前创建日期 bool SetLocalFileTime(const char* FilePath, const char* Date, const char* Time) { HANDLE hFile = CreateFileA(FilePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); if (hFile == INVALID_HANDLE_VALUE) { return false; } SYSTEMTIME spec_time; sscanf(Date, "%d-%d-%d", &spec_time.wYear, &spec_time.wMonth, &spec_time.wDay); sscanf(Time, "%d:%d:%d", &spec_time.wHour, &spec_time.wMinute, &spec_time.wSecond); FILETIME ft, LocalFileTime; SystemTimeToFileTime(&spec_time, &ft); LocalFileTimeToFileTime(&ft, &LocalFileTime); if (SetFileTime(hFile, &LocalFileTime, // 创建时间 &LocalFileTime, // 访问时间 &LocalFileTime // 修改时间 )) { CloseHandle(hFile); return true; } CloseHandle(hFile); return false; } // 批量修改文件名 void BatchSetFileDateTime(string folderPath, string Date, string Time) { _finddata_t FileInfo; string strfind = folderPath + "\\*"; long Handle = _findfirst(strfind.c_str(), &FileInfo); if (Handle == NULL) { exit(0); } do { // 判断是否为目录 if (FileInfo.attrib & _A_SUBDIR) { // 判断目录是否为当前目录和上一级目录 if ((strcmp(FileInfo.name, ".") != 0) && (strcmp(FileInfo.name, "..") != 0)) { // 如果不是则拼接当前路径继续递归调用 string newPath = folderPath + "\\" + FileInfo.name; bool ref = SetLocalFileTime(newPath.c_str(), Date.c_str(), Time.c_str()); if (ref == true) { std::cout << "[*] 目录: " << newPath.c_str() << std::endl; } BatchSetFileDateTime(newPath, Date, Time); } } else { string newPath = folderPath + "\\" + FileInfo.name; bool ref = SetLocalFileTime(newPath.c_str(), "1995-01-01", "12:00:00"); if (ref == true) { std::cout << "[*] 文件: " << newPath.c_str() << std::endl; } } } while (_findnext(Handle, &FileInfo) == 0); _findclose(Handle); } int main(int argc, char* argv[]) { BatchSetFileDateTime("D:\\lyshark", "1995-01-01", "0:0:0"); system("pause"); return 0; }
运行后,目录下的文件将被重置时间戳;
到此这篇关于C/C++实现重置文件时间戳的文章就介绍到这了,更多相关C++重置文件时间戳内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!