C/C++實(shí)現(xiàn)重置文件時(shí)間戳
1.切割文件名與路徑
如下代碼是一段文件路徑切割實(shí)現(xiàn),通過(guò)傳入文件路徑,獲取文件名和文件路徑的功能。具體實(shí)現(xiàn)包括兩個(gè)函數(shù):GetFileName
和GetFilePath
。前者接收一個(gè)文件路徑字符串,并返回該文件路徑中的文件名;后者接收一個(gè)文件路徑字符串,并返回該文件路徑中除文件名以外的部分,即文件路徑。
在main
函數(shù)中,首先定義了兩個(gè)文件路徑字符串szPathA
和szPathB
。然后,分別調(diào)用GetFileName
和GetFilePath
函數(shù),將它們的返回值保存在指針變量ptr
中,并輸出到控制臺(tái)上。最后,程序返回0,結(jié)束執(zhí)行。
#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; }
傳入一個(gè)完整文件路徑,并自動(dòng)分割;
2.遍歷目錄下文件
如下代碼是一個(gè)使用遞歸遍歷目錄,并輸出指定格式的文件信息的程序。主要用到了文件操作函數(shù)findfirst()
、_findnext()
和_findclose()
,以及結(jié)構(gòu)體類(lèi)型_finddata_t
。
findfirst函數(shù)是Windows
平臺(tái)上用于查找文件的函數(shù)之一,它屬于 C Runtime Library(CRT)
中的一部分,提供了一種在指定目錄中搜索文件的機(jī)制。
定義:
intptr_t _findfirst( const char *filespec, struct _finddata_t *fileinfo );
參數(shù):
- filespec:指定要搜索的文件規(guī)范(通配符模式),可以包含路徑信息。
- fileinfo:指向 finddata_t 結(jié)構(gòu)的指針,用于存儲(chǔ)找到的文件信息。
返回值:
如果成功,返回一個(gè)查找句柄(handle);如果失敗,返回 -1。
findnext函數(shù)是Windows
平臺(tái)上用于查找文件的函數(shù)之一,它通常與_findfirst
配合使用,用于獲取指定目錄中的下一個(gè)文件。
定義:
int _findnext( intptr_t handle, struct _finddata_t *fileinfo );
參數(shù):
- handle:由
findfirst
返回的查找句柄。 - fileinfo:指向
finddata_t
結(jié)構(gòu)的指針,用于存儲(chǔ)找到的下一個(gè)文件的信息。
返回值:
如果成功,返回 0;如果失敗或到達(dá)目錄尾部,返回 -1。
函數(shù)dfsFolder()
分別接收目錄路徑和需要查找的文件格式。通過(guò)使用_findfirst()
找到該路徑下的第一個(gè)文件或文件夾,如果是文件夾,則遞歸調(diào)用dfsFolder()
函數(shù),如果是文件,則判斷其是否為需要查找的格式,如果是則輸出該文件的相關(guān)信息。
函數(shù)dfsFolderAll()
只傳入了一個(gè)參數(shù),即目錄路徑。該函數(shù)使用了和dfsFolder()
類(lèi)似的方法,但是不判斷文件格式,而是將該路徑下的所有文件和文件夾都列出來(lái),在main()
函數(shù)中,可以通過(guò)調(diào)用這兩個(gè)函數(shù)來(lái)實(shí)現(xiàn)列出目錄下所有文件和文件夾,或是列出目錄下所有指定格式的文件。
#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; /* 文件信息結(jié)構(gòu)體 struct _finddata_t{ unsigned attrib; // 文件屬性 time_t time_create; // 創(chuàng)建時(shí)的時(shí)間戳 time_t time_access; // 最后一次被訪(fǎng)問(wèn)時(shí)的時(shí)間戳 time_t time_write; // 最后一次被修改時(shí)的時(shí)間戳 _fsize_t size; // 文件字節(jié)大小 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) { // 判斷目錄是否為當(dāng)前目錄和上一級(jí)目錄 if ((strcmp(FileInfo.name, ".") != 0) && (strcmp(FileInfo.name, "..") != 0)) { // 如果不是則拼接當(dāng)前路徑繼續(xù)遞歸調(diào)用 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 << " 系統(tǒng)文件 " << 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; }
運(yùn)行后輸出所有C:\\Windows\\system32\\*
目錄下的文件;
3.重置文件目錄時(shí)間戳
文件目錄時(shí)間戳是指與文件或目錄相關(guān)聯(lián)的時(shí)間信息,通常包括三個(gè)主要的時(shí)間戳:
- 創(chuàng)建時(shí)間(Creation Time): 表示文件或目錄被創(chuàng)建的時(shí)間。這個(gè)時(shí)間戳記錄了文件或目錄在文件系統(tǒng)中第一次被創(chuàng)建的時(shí)間點(diǎn)。
- 最后訪(fǎng)問(wèn)時(shí)間(Last Access Time): 表示文件或目錄最后一次被訪(fǎng)問(wèn)的時(shí)間。每當(dāng)文件或目錄被打開(kāi)、讀取、執(zhí)行等操作時(shí),最后訪(fǎng)問(wèn)時(shí)間都會(huì)更新。
- 最后修改時(shí)間(Last Write Time): 表示文件或目錄最后一次被修改的時(shí)間。當(dāng)文件內(nèi)容發(fā)生變化、文件被寫(xiě)入時(shí),最后修改時(shí)間會(huì)更新。
這些時(shí)間戳提供了關(guān)于文件或目錄的重要信息,對(duì)于文件管理和調(diào)查文件活動(dòng)非常有用。在Windows和許多其他操作系統(tǒng)中,這些時(shí)間戳通常以 FILETIME 結(jié)構(gòu)體的形式存儲(chǔ),該結(jié)構(gòu)體表示從1601年1月1日午夜開(kāi)始計(jì)算的100納秒間隔數(shù)。
這些時(shí)間戳可以通過(guò)文件系統(tǒng)或相關(guān)的系統(tǒng)調(diào)用函數(shù)(如 GetFileTime、SetFileTime)來(lái)訪(fǎng)問(wèn)和修改。
SystemTimeToFileTime 用于將SYSTEMTIME
結(jié)構(gòu)體表示的時(shí)間轉(zhuǎn)換為FILETIME
結(jié)構(gòu)體表示的時(shí)間。
函數(shù)簽名:
BOOL SystemTimeToFileTime( const SYSTEMTIME *lpSystemTime, LPFILETIME lpFileTime );
參數(shù):
- lpSystemTime:指向 SYSTEMTIME 結(jié)構(gòu)體的指針,表示待轉(zhuǎn)換的系統(tǒng)時(shí)間。
- lpFileTime:指向 FILETIME 結(jié)構(gòu)體的指針,用于存儲(chǔ)轉(zhuǎn)換后的文件時(shí)間。
返回值:
如果函數(shù)成功,返回非零值;如果函數(shù)失敗,返回零??梢酝ㄟ^(guò)調(diào)用 GetLastError 函數(shù)獲取更多信息。
LocalFileTimeToFileTime 用于將本地時(shí)間(FILETIME 結(jié)構(gòu)體表示)轉(zhuǎn)換為協(xié)調(diào)世界時(shí)(UTC)時(shí)間(同樣是 FILETIME 結(jié)構(gòu)體表示)。
函數(shù)簽名:
BOOL LocalFileTimeToFileTime( const FILETIME *lpLocalFileTime, LPFILETIME lpFileTime );
參數(shù):
- lpLocalFileTime:指向 FILETIME 結(jié)構(gòu)體的指針,表示待轉(zhuǎn)換的本地時(shí)間。
- lpFileTime:指向 FILETIME 結(jié)構(gòu)體的指針,用于存儲(chǔ)轉(zhuǎn)換后的 UTC 時(shí)間。
返回值:
如果函數(shù)成功,返回非零值;如果函數(shù)失敗,返回零??梢酝ㄟ^(guò)調(diào)用 GetLastError 函數(shù)獲取更多信息。
SetFileTime 用于設(shè)置指定文件的創(chuàng)建時(shí)間、訪(fǎng)問(wèn)時(shí)間和修改時(shí)間。
函數(shù)簽名:
BOOL SetFileTime( HANDLE hFile, const FILETIME *lpCreationTime, const FILETIME *lpLastAccessTime, const FILETIME *lpLastWriteTime );
參數(shù):
- hFile:要設(shè)置時(shí)間信息的文件的句柄。
- lpCreationTime:指向 FILETIME 結(jié)構(gòu)體的指針,表示文件的創(chuàng)建時(shí)間。
- lpLastAccessTime:指向 FILETIME 結(jié)構(gòu)體的指針,表示文件的最后訪(fǎng)問(wèn)時(shí)間。
- lpLastWriteTime:指向 FILETIME 結(jié)構(gòu)體的指針,表示文件的最后修改時(shí)間。
返回值:
如果函數(shù)成功,返回非零值;如果函數(shù)失敗,返回零。可以通過(guò)調(diào)用 GetLastError 函數(shù)獲取更多信息。
#include <io.h> #include <iostream> #include <windows.h> using namespace std; // 修改文件當(dāng)前創(chuàng)建日期 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, // 創(chuàng)建時(shí)間 &LocalFileTime, // 訪(fǎng)問(wèn)時(shí)間 &LocalFileTime // 修改時(shí)間 )) { 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) { // 判斷目錄是否為當(dāng)前目錄和上一級(jí)目錄 if ((strcmp(FileInfo.name, ".") != 0) && (strcmp(FileInfo.name, "..") != 0)) { // 如果不是則拼接當(dāng)前路徑繼續(xù)遞歸調(diào)用 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; }
運(yùn)行后,目錄下的文件將被重置時(shí)間戳;
到此這篇關(guān)于C/C++實(shí)現(xiàn)重置文件時(shí)間戳的文章就介紹到這了,更多相關(guān)C++重置文件時(shí)間戳內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- c++打印封裝每次打印前面加上時(shí)間戳問(wèn)題
- 關(guān)于C++使用std::chrono獲取當(dāng)前秒級(jí)/毫秒級(jí)/微秒級(jí)/納秒級(jí)時(shí)間戳問(wèn)題
- C++?std::chrono庫(kù)使用示例(實(shí)現(xiàn)C++?獲取日期,時(shí)間戳,計(jì)時(shí)等功能)
- C++ 中時(shí)間與時(shí)間戳的轉(zhuǎn)換實(shí)例詳解
- C++時(shí)間戳轉(zhuǎn)化操作實(shí)例分析【涉及GMT與CST時(shí)區(qū)轉(zhuǎn)化】
- C++時(shí)間戳轉(zhuǎn)換成日期時(shí)間的步驟和示例代碼
- c++之time_t和struct tm及時(shí)間戳的正確使用方式
相關(guān)文章
C語(yǔ)言關(guān)于二叉樹(shù)中堆的創(chuàng)建和使用整理
大家好,這里是針對(duì)二叉樹(shù)中堆結(jié)構(gòu)的順序儲(chǔ)存,整理出來(lái)一篇博客供我們一起復(fù)習(xí)和學(xué)習(xí),如果文章中有理解不當(dāng)?shù)牡胤?還希望朋友們?cè)谠u(píng)論區(qū)指出,我們相互學(xué)習(xí),共同進(jìn)步2022-08-08

c++中移動(dòng)語(yǔ)義和完美轉(zhuǎn)發(fā)及易錯(cuò)點(diǎn)

C語(yǔ)言中g(shù)etchar(?)?函數(shù)使用詳解

Qt編寫(xiě)地圖實(shí)現(xiàn)閃爍點(diǎn)圖的示例代碼

C語(yǔ)言與C++動(dòng)態(tài)通訊錄超詳細(xì)實(shí)現(xiàn)流程

c語(yǔ)言求出給定范圍內(nèi)的所有質(zhì)數(shù)