c++ 我在Windows操作系统上获取文件创建日期的方法导致我的控制台应用程序崩溃。

7 浏览
0 Comments

c++ 我在Windows操作系统上获取文件创建日期的方法导致我的控制台应用程序崩溃。

当我调用Created方法时,它会导致我的控制台应用程序崩溃。如果我把它注释掉,我的程序就可以正常运行。我想要获取共享网络驱动器(Windows操作系统)上文件的创建日期,但我无法找出错误在哪里。我只想要能够获取文件创建的时间戳。如果我可以修复这个方法来完成这个功能就太好了。如果不能,任何能够产生文件创建时间戳的替代方法也可以接受。非常感谢任何帮助或指导。

#pragma comment(lib, "th32.lib")
#define VC_EXTRALEAN
#include "stdafx.h"
#include 
#include 
#include 
#include 
#include 
//#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;
//返回最后的Win32错误,以字符串格式返回。如果没有错误,则返回空字符串。
std::string GetLastErrorAsString()
{
    //获取错误消息(如果有)。
    DWORD errorMessageID = ::GetLastError();
    if(errorMessageID == 0)
        return std::string(); //没有记录错误消息
    LPSTR messageBuffer = nullptr;
    size_t size = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
                                 NULL, errorMessageID, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&messageBuffer, 0, NULL);
    std::string message(messageBuffer, size);
    //释放缓冲区。
    LocalFree(messageBuffer);
    return message.c_str();
}
__int64 FileSize(const wchar_t* name) //, bool _true
{
    WIN32_FILE_ATTRIBUTE_DATA fad;
    std::wstring temp;
    wchar_t* created;
    wchar_t* error;
    if (!GetFileAttributesEx(name, GetFileExInfoStandard, &fad))
    {
        error = L"错误";
        return -1; //错误条件,可以调用GetLastError了解更多信息
    }
    LARGE_INTEGER size;
    size.HighPart = fad.nFileSizeHigh;
    size.LowPart = fad.nFileSizeLow;
    //return (wchar_t*) size.QuadPart;
    return size.QuadPart;
}
const wchar_t* Created(const wchar_t* name) //, bool _true
{
    WIN32_FILE_ATTRIBUTE_DATA fad;
    //std::wstring temp;
    std::wstring created;
    SYSTEMTIME st;
    if (!GetFileAttributesEx(name, GetFileExInfoStandard, &fad))
    {
        std::wstring error(L"错误");
        return error.c_str(); //错误条件,可以调用GetLastError了解更多信息
    }
    if (!FileTimeToSystemTime(&fad.ftCreationTime, &st))
    {
        std::wstring error(L"获取创建时间错误");
        return error.c_str(); //错误条件,可以调用GetLastError了解更多信息
    }
    std::wstring month((wchar_t*)st.wMonth);
    std::wstring day((wchar_t*)st.wDay);
    std::wstring year((wchar_t*)st.wYear);
    created = month + L"/" + day + L"/" + year;
    //created = temp.c_str();
    //created = st.wMonth + '/' + st.wDay + '/' + st.wYear;
    return created.c_str();
}
int _tmain(int argc, _TCHAR* argv[])
{   
    std::wstring ap(L"//S001E002/某个文件夹/");
    std::wstring all(L"*");
    std::wstring temp = ap + all;
    const wchar_t* Hotels = temp.c_str();
    const wchar_t* current = L".";
    const wchar_t* parent = L"..";
    wchar_t* pdf = L"/*.??f\0";
    wchar_t* tif = L"/*.*f";
    WIN32_FIND_DATA FindFileData;
    std::vector folders;
    std::vector vs;
    HANDLE hFind;
    std::wcout << "酒店文件夹目录: " << Hotels << "\n";
    hFind = FindFirstFile(Hotels, &FindFileData);
    if (hFind != INVALID_HANDLE_VALUE) 
    {
        do {
            {   
                if(FindFileData.dwFileAttributes & _A_SUBDIR)
                {
                    temp = FindFileData.cFileName;
                    if ( wcscmp(temp.c_str(), current) == 0 ||  wcscmp(temp.c_str(), parent) == 0 ) {}
                    else
                    {
                        folders.push_back(FindFileData.cFileName);
                        std::wcout << "文件夹: " << FindFileData.cFileName << "\n";
                        //std::wcout << " equal? " << current << " : " << temp << " : " << parent << "\n";
                    }
                }
            }
        } while (FindNextFile(hFind, &FindFileData));
        FindClose(hFind);
    }
    //std::wcout << "Folder: " << str << "\n";
    for (int i = 0; i < folders.size(); i++)
    {
        //folders[i]
        temp = ap + folders[i] + pdf;
        const wchar_t* _files = temp.c_str();
        std::wcout << "文件目录: " << _files << "\n";
        hFind = FindFirstFile(_files, &FindFileData);
        if (hFind != INVALID_HANDLE_VALUE) 
        {
            do {
                {   
                    temp = FindFileData.cFileName;
                    if ( wcscmp(temp.c_str(), current) == 0 ||  wcscmp(temp.c_str(), parent) == 0 ) {}
                    else
                    {
                        //std::wcout << "File: "<< FindFileData.cFileName ;
                        //std::wcout << " equal? " << current << " : " << temp << " : " << parent << "\n";
                        temp = ap + folders[i] + L"/" + FindFileData.cFileName;
                        vs.push_back(temp); 
                    }
                }
            } while (FindNextFile(hFind, &FindFileData));
            FindClose(hFind);
        }
        else 
        {
            temp = ap + folders[i] + L"/";
            std::wcout << temp.c_str() << " | ";
            std::cout << GetLastErrorAsString() << "\n";
        }
    }
    /*for (auto item : vs)
        std::wcout << item << "\n";*/
    __int64 size;
    const wchar_t* created;
    std::cout << "\n" << "开始文件统计" << "\n";
    for (int i = 0; i < vs.size(); i++)
    {
        size =  FileSize(vs[i].c_str());
        created = Created(vs[i].c_str());
        std::wcout << vs[i] << " | 文件大小: ";
        std::wcout << size ;
        std::wcout << " | 创建时间: " << created << " | 错误: " << GetLastErrorAsString; 
        std::wcout << "\n"; // , 1 << FileSize(vs[i].c_str(), 0)
    }
    std::cout << "\n" << "结束文件统计" << "\n";
    std::cout << GetLastErrorAsString() << "\n";
    std::cout << "文件夹数量: " << folders.size() << "\n";
    std::cout << "文件数量: " << vs.size() << "\n";
    return 0;
}

0
0 Comments

问题的出现原因是在代码中使用了错误的类型转换和函数调用。首先,在获取文件创建日期时,使用了错误的类型转换方法将整数转换为字符串,应该使用std::to_wstring函数来进行转换。其次,使用了错误的函数GetLastErrorAsString,该函数返回的是ANSI字符串,而程序中使用的是Unicode字符串,应该使用Unicode版本的std::wcout来输出错误信息。此外,在判断文件是否是目录时,使用了错误的标志位_A_SUBDIR,应该使用FILE_ATTRIBUTE_DIRECTORY来判断。最后,在格式化日期时间时,使用了错误的方法,应该使用std::wostringstream和std::setfill来进行格式化。

解决方法是将代码中的错误部分进行修改。首先,将类型转换部分修改为使用std::to_wstring函数,同时移除错误的.c_str()调用。然后,将输出错误信息的部分修改为使用std::wcout来输出Unicode字符串。接下来,将判断文件是否是目录的标志位修改为FILE_ATTRIBUTE_DIRECTORY。最后,将格式化日期时间的部分修改为使用std::wostringstream和std::setfill来进行格式化。

修改后的代码如下:

std::wstring month = std::to_wstring(st.wMonth);
std::wstring day = std::to_wstring(st.wDay);
std::wstring year = std::to_wstring(st.wYear);
created = month + L"/" + day + L"/" + year;
...
std::wcout << GetLastErrorAsString() << "\n";
...
if (FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
...
std::wostringstream oss;
oss << std::setfill(L'0');
oss 
    << st.wMonth << L"/" 
    << st.wDay << L"/" 
    << st.wYear << L" " 
    << std::setw(2) << st.wHour << L":" 
    << std::setw(2) << st.wMinute << L":" 
    << std::setw(2) << st.wSecond;
created = oss.str();
...
wchar_t buf[100];
GetDateFormat(0, 0, &st, 0, buf, 100);
created = buf;
GetTimeFormat(0, 0, &st, 0, buf, 100);
created += std::wstring(L" ") + buf;

此外,还需要注意在使用Visual Studio 2010时,需要进行额外的修复,即将st的类型转换为long long,然后使用std::to_wstring进行转换。

以上是问题出现的原因和解决方法的整理。

0