C++ 删除超过30天的文件

C++ 删除超过30天的文件,c++,windows,winapi,C++,Windows,Winapi,我一直试图删除一个超过30天的文件夹中的文件, 下面是我试图获取文件保存日期的代码,但它没有清晰地返回 charc_szText[_MAX_PATH]; wcstombs(c_szText,用户名,wcslen(用户名)+1); std::string Fstr(“c:\\Users\\username\\AppData\\Test\\\*”; Fstr.替换(9、8、c_szText); 常数时间=时间(空); struct tm*tl=本地时间(&t); WIN32_查找_数据信息; 处理

我一直试图删除一个超过30天的文件夹中的文件, 下面是我试图获取文件保存日期的代码,但它没有清晰地返回

charc_szText[_MAX_PATH];
wcstombs(c_szText,用户名,wcslen(用户名)+1);
std::string Fstr(“c:\\Users\\username\\AppData\\Test\\\*”;
Fstr.替换(9、8、c_szText);
常数时间=时间(空);
struct tm*tl=本地时间(&t);
WIN32_查找_数据信息;
处理高压;
hp=FindFirstFile(str2.c_str(),&info);
做
{
文件时间ftCreate、ftAccess、ftWrite;
系统时间stUTC,stLocal;
德沃德·德雷特;
LPTSTR-lpszString;
GetFileTime(hp、ftCreate、ftAccess和ftWrite);
//将上次写入时间转换为本地时间。
FileTimeToSystemTime(&ftWrite,&stUTC);
SystemTimeToTzSpecificClocalTime(NULL、stUTC和stLocal);
如果(tl->tm_年+1900>stLocal.wYear)
{ 
删除文件(info.cFileName);
}
如果((tl->tm_mon-((stLocal.wMonth)-1))>1,则为else
{
删除文件(info.cFileName);
}
else if(tl->tm_mon>((stLocal.wMonth)-1))
{

如果(tl->tm_mday不需要将
FILETIME
转换为
SYSTEMTIME
FILETIME
基本上是一个以100ns为单位的
\u int64
时间值(从一些参考时间开始),这正是进行时间比较所需要的


只需通过
GetSystemTimeAsFileTime
获取当前时间,从中减去30天,这将是您的阈值。

无需将Unicode字符串转换为MBCS。使用基于
WCHAR
FindFirstFile()
函数,而不是基于
TCHAR
FindFirstFile()
功能


无需将时间转换为本地时区。文件时间以UTC表示,您可以以UTC检索当前系统时钟时间。然后您可以比较这两个值,而无需转换它们

此外,您没有正确检索文件时间。您将错误的
句柄
传递到
GetFileTime()
。它需要打开文件的句柄,但您将其传递给搜索对象的句柄。
WIN32\u FIND\u DATA
已经包含文件时间,您不需要手动检索它们

另外,您只将文件名传递给
DeleteFile()
WIN32\u FIND\u DATA
只包含文件名,而不包含文件夹路径。如果您不在文件夹路径前加前缀,
DeleteFile()
将文件名解释为相对于调用进程的当前工作目录,这是不保证的(或可能的)位于您期望的文件夹中

尝试类似以下内容:

/* helper macros, courtesy of MSDN:
https://support.microsoft.com/en-us/help/188768/info-working-with-the-filetime-structure
*/
#define FT_SECOND ((INT64) 10000000)
#define FT_MINUTE (60 * FT_SECOND)
#define FT_HOUR   (60 * FT_MINUTE)
#define FT_DAY    (24 * FT_HOUR)

/*
Note: you really should be using SHGetFilePath() or SHGetKnownFolderPath()
to retrieve a given user's APPDATA folder location...
*/
std::wstring Ffolder = L"c:\\Users\\" + std::wstring(username) + L"\\AppData\\Test\\";
/* alternatively:
std::wostringstream wos;
wos << L"c:\\Users\\" << username << L"\\AppData\\Test\\";
std::wstring Ffolder = wos.str();
*/

// get today @ 00:00:00:00 time, in UTC...
SYSTEMTIME stUTC = {0};
GetSystemTime(&stUTC);
stUTC.wHour = stUTC.wMinute = stUTC.wSecond =  stUTC.wMilliseconds = 0;

// subtract 30 days from it...
FILETIME ft30DaysAgo = {0};
ULARGE_INTEGER ul;
SystemTimeToFileTime(&stUTC, &ft30DaysAgo);
ul.LowPart = ft30DaysAgo.dwLowDateTime;
ul.HighPart = ft30DaysAgo.dwHighDateTime;
ul.QuadPart -= (30 * FT_DAY);
ft30DaysAgo.dwLowDateTime = ul.LowPart;
ft30DaysAgo.dwHighDateTime = ul.HighPart;

// now search for files...
WIN32_FIND_DATAW info;
HANDLE hp = FindFirstFileW((Ffolder + L"*").c_str(), &info);
if (hp != INVALID_HANDLE_VALUE)
{
    do
    {
        if (
            // process only files...
            ((info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0) &&
            // that have a last-write time...
            ((info.ftLastWriteTime.dwLowDateTime != 0) || (info.ftLastWriteTime.dwHighDateTime != 0)) &&
            // older than 30 days...
            (CompareFileTime(&(info.ftLastWriteTime), &ft30DaysAgo) < 0)
            )
        {
            // bye bye!!
            DeleteFileW((Ffolder + info.cFileName).c_str());
        }
    }
    while (FindNextFile(hp, &info));
    FindClose(hp);
}
/*帮助程序宏,由MSDN提供:
https://support.microsoft.com/en-us/help/188768/info-working-with-the-filetime-structure
*/
#定义英尺秒((INT64)10000000)
#定义英尺/分钟(60*英尺/秒)
#定义英尺小时(60*英尺分钟)
#定义英尺日(24*英尺小时)
/*
注意:您确实应该使用SHGetFilePath()或SHGetKnownFolderPath()
要检索给定用户的APPDATA文件夹位置。。。
*/
std::wstring Ffolder=L“c:\\Users\\”+std::wstring(username)+L“\\AppData\\Test\\”;
/*或者:
std::wostringstream-wos;

你所说的“它没有清晰地返回”是什么意思?您得到了什么值?您在哪里初始化
t1
。请尽可能减少您的问题。例如,让程序在命令行上获取一个文件,只打印最后一次写入时间,然后告诉我们您得到了什么值,以及您想要什么值。我们需要一个解决方案。您是否考虑过进行一些调试对你来说,这不是比我们更容易做到吗?你是否意识到你的代码根本不执行错误检查。这是一个巨大的错误,似乎是大多数初学者犯的。不要忽略错误检查。既然我是初学者,你能提供一个代码,我需要在其中进行更改以获得结果。既然你是初学者,为什么不尝试学习y我们自己,而不是被填鸭式喂养。
/* helper macros, courtesy of MSDN:
https://support.microsoft.com/en-us/help/188768/info-working-with-the-filetime-structure
*/
#define FT_SECOND ((INT64) 10000000)
#define FT_MINUTE (60 * FT_SECOND)
#define FT_HOUR   (60 * FT_MINUTE)
#define FT_DAY    (24 * FT_HOUR)

/*
Note: you really should be using SHGetFilePath() or SHGetKnownFolderPath()
to retrieve a given user's APPDATA folder location...
*/
std::wstring Ffolder = L"c:\\Users\\" + std::wstring(username) + L"\\AppData\\Test\\";
/* alternatively:
std::wostringstream wos;
wos << L"c:\\Users\\" << username << L"\\AppData\\Test\\";
std::wstring Ffolder = wos.str();
*/

// get today @ 00:00:00:00 time, in UTC...
SYSTEMTIME stUTC = {0};
GetSystemTime(&stUTC);
stUTC.wHour = stUTC.wMinute = stUTC.wSecond =  stUTC.wMilliseconds = 0;

// subtract 30 days from it...
FILETIME ft30DaysAgo = {0};
ULARGE_INTEGER ul;
SystemTimeToFileTime(&stUTC, &ft30DaysAgo);
ul.LowPart = ft30DaysAgo.dwLowDateTime;
ul.HighPart = ft30DaysAgo.dwHighDateTime;
ul.QuadPart -= (30 * FT_DAY);
ft30DaysAgo.dwLowDateTime = ul.LowPart;
ft30DaysAgo.dwHighDateTime = ul.HighPart;

// now search for files...
WIN32_FIND_DATAW info;
HANDLE hp = FindFirstFileW((Ffolder + L"*").c_str(), &info);
if (hp != INVALID_HANDLE_VALUE)
{
    do
    {
        if (
            // process only files...
            ((info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0) &&
            // that have a last-write time...
            ((info.ftLastWriteTime.dwLowDateTime != 0) || (info.ftLastWriteTime.dwHighDateTime != 0)) &&
            // older than 30 days...
            (CompareFileTime(&(info.ftLastWriteTime), &ft30DaysAgo) < 0)
            )
        {
            // bye bye!!
            DeleteFileW((Ffolder + info.cFileName).c_str());
        }
    }
    while (FindNextFile(hp, &info));
    FindClose(hp);
}