我有以下代码在我的产品中查找文件:
destFolder = "c:\\myproduct\\base\\";
//download and unzip whoisactive.zip from some websites to the installation folder of my product
DownloadAndUnzipSql( "http://www.whoisactive.com/whoisactive.zip", destFolder)
WIN32_FIND_DATA ffd;
HANDLE hFind = FindFirstFile(destFolder.c_str(), &ffd);
do {
if (!(ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
if ((string(ffd.cFileName).find("whoisactive") != string::npos) && (string(ffd.cFileName).find("sql") != string::npos)){
MoveFile(ffd.cFileName, sqlFile.c_str());
log.Debug(__FUNCTION__, "Succeed to rename file.");
break;
}
}
} while (FindNextFile(hFind, &ffd) != 0);
FindClose(hFind);
以前工作得非常好,但它最近一个月内无法找到下载的whoisactive.sql。我检查了c:\ myproduct \ base \,whoisactive.sql在那里,但当我转储所有文件FindFirstFile和FindNextFile返回时,没有包含whoisactive.sql。
我不认为它是由防病毒软件引起的,因为在产品环境中没有安装此类软件。我并不认为它的权限问题,因为whoisactive.sql是正确下载和解压缩的。
我搜索了我的问题,发现了以下两篇文章: https://social.msdn.microsoft.com/Forums/vstudio/en-US/4659a528-dd51-4749-b751-a491bbdf5fa0/findfirstfile-caching?forum=vcgeneral Does FindFirstFile/FindNextFile API pair cache results returned?
似乎FindFirstFile将缓存目录的文件列表,因此有时我们可能找不到新添加的文件。但我也不认为这也是根本原因,因为我的代码在去年运行得很好并且从未失败,这很奇怪,而且最近一个月找不到whoisactive.sql突然间,直到现在都没有工作。如果缓存问题是根本原因,那么为什么我现在总能重现问题呢?奇怪的是代码仍然可以在我的开发环境中工作,但它不能在产品环境中工作。
所以我将代码更改为以下内容,然后它在产品和开发环境中都有效:
destFolder = "c:\\myproduct\\base\\";
//download whoisactive.zip from some websites to the installation folder of my product
Download( "http://www.whoisactive.com/whoisactive.zip", destFolder);
//Unzip the whoisactive.zip and get the extracted file list.
string fileList;
Unzip(destFolder+"\\whoisactive.zip", fileList);
for (int i=0; i<fileList.size(); ++i) {
if (fileList[i].find("sql") != string::npos && fileList[i].find("whoisactive") != string::npos) {
string srcFile = destFolder+"\\"+fileList[i];
string dstFile = destFolder+"\\"+sqlFile;
if (DeleteFile(dstFile.c_str()) == 0)
log.Debug(__FUNCTION__, "Failed to delete file %s, error code is %d.", dstFile.c_str(), GetLastError());
if (MoveFile(srcFile.c_str(), dstFile.c_str()) == 0)
log.Debug(__FUNCTION__, "Failed to rename file %s, error code is %d.", srcFile.c_str(), GetLastError());
break;
}
}
您可以看到更改是我不再在我的代码中使用FindFirstFile和FindNextFile,我只是从zip文件中提取文件名并直接访问该文件。那么请你告诉我为什么FindFirstFile和FindNextFile在我以前的代码中找不到下载的sql文件?感谢。
答案 0 :(得分:1)
您根本没有搜索目录的内容。您正在将目录本身仅原样("c:\\myproduct\\base\\"
)传递给FindFirstFile()
,这样就可以找到 - 目录本身的属性,没有别的。
要正确枚举目录,您需要执行通配符搜索。将*
或*.*
附加到目录路径的末尾,例如:
destFolder = "c:\\myproduct\\base\\";
//download and unzip whoisactive.zip from some websites to the installation folder of my product
DownloadAndUnzipSql("http://www.whoisactive.com/whoisactive.zip", destFolder);
WIN32_FIND_DATA ffd;
HANDLE hFind = FindFirstFileA((destFolder + "*.*").c_str(), &ffd);
if (hFind != INVALID_HANDLE_VALUE) {
do {
if (!(ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
if (lstrcmpiA(ffd.cFileName, "whoisactive.sql") == 0) {
if (MoveFileA((destFolder + ffd.cFileName).c_str(), (destFolder + sqlFile).c_str()))
log.Debug(__FUNCTION__, "Succeed to rename file.");
else
log.Debug(__FUNCTION__, "Failed to rename file, error code is %d.", GetLastError());
break;
}
}
}
while (FindNextFileA(hFind, &ffd));
if (GetLastError() != ERROR_NO_MORE_FILES) {
log.Debug(__FUNCTION__, "Failed to find next file, error code is %d.", GetLastError());
}
FindClose(hFind);
}
else if (GetLastError() == ERROR_FILE_NOT_FOUND) {
log.Debug(__FUNCTION__, "No files found.");
}
else {
log.Debug(__FUNCTION__, "Failed to find first file, error code is %d.", GetLastError());
}
但是,由于您只对特定文件感兴趣,因此根本不需要使用Find(First|Next)File()
。只要无条件地调用MoveFile()
,如果文件不存在就让它失败:
destFolder = "c:\\myproduct\\base\\";
//download and unzip whoisactive.zip from some websites to the installation folder of my product
DownloadAndUnzipSql("http://www.whoisactive.com/whoisactive.zip", destFolder);
if (MoveFileA((destFolder + "whoisactive.sql").c_str(), (destFolder + sqlFile).c_str()))
log.Debug(__FUNCTION__, "Succeed to rename file.");
else
log.Debug(__FUNCTION__, "Failed to rename file, error code is %d.", GetLastError());