今天在调试程序时发现一个 WIN32_FIND_DATA 的BUG,在循环读取一个文件夹下的图片文件时,发现结构体中 nFileSizeLow 和 nFileSizeHigh 值 == 0的情况,即能获取到文件名,但读出的文件大小为0的尴尬情况。但事实上,图片文件是正常的,大小从80K~170K的都有,比较诡异,与各位分享一下。
typedef struct _WIN32_FIND_DATAW {
DWORD dwFileAttributes;
FILETIME ftCreationTime;
FILETIME ftLastAccessTime;
FILETIME ftLastWriteTime;
DWORD nFileSizeHigh;
DWORD nFileSizeLow;
DWORD dwReserved0;
DWORD dwReserved1;
WCHAR cFileName[ MAX_PATH ];
WCHAR cAlternateFileName[ 14 ];
#ifdef _MAC
DWORD dwFileType;
DWORD dwCreatorType;
WORD wFinderFlags;
#endif
} WIN32_FIND_DATAW, *PWIN32_FIND_DATAW, *LPWIN32_FIND_DATAW;
现场情况如下:在磁盘上指定一个文件目录,有其他的进程不定时的往该目录下放入指定格式的JPG文件,而当前进程会循环去检索该目录,发现指定格式的JPG文件,就读取并做处理。代码如下:
WIN32_FIND_DATA data, cjpg;
HANDLE hFind = NULL;
String c_jpgname;
bool bok = true;
for(hFind = FindFirstFile((pic_store_path + "*.jpg").c_str(), &data);
hFind && bok && FileExists(pic_store_path + data.cFileName); bok = FindNextFile(hFind, &data))
{
c_jpgname = data.cFileName;
//问题出现在此处,我想检索一下读取的每个文件大小,小于5K的图片认为是有问题的,需要处理,蓝色部分是代码
if(data.nFileSizeLow < 5120 && data.nFileSizeHigh == 0)
{
write_log("[uploadXML][%d,%d][%s].", data.nFileSizeHigh, data.nFileSizeLow, c_jpgname);
write_log("[uploadXML] 图片异常,存入ERROR目录。");
if(FileExists(pic_error_path + data.cFileName))
{
DeleteFile(pic_error_path + data.cFileName);
}
//图片大小异常,存放到ERROR文件夹
MoveFile((pic_store_path + data.cFileName).c_str(), (pic_error_path + data.cFileName).c_str());
continue;
}
//实际的文件处理代码
}
if(hFind)
{
FindClose(hFind);
} else
{
Sleep(100);
}
但在测试结果时发现,有大小为80K~178K大小不等的图片也会放到ERROR文件夹下,这时的打印大小为 [0,0],在ERROR目录下查看这些文件并没有什么异常,当把这些图片放到正确目录下继续执行的话,就不会打印大小为0了。
只好进行修改将大小为0的情况,例外处理。
if(data.nFileSizeLow < 5120 && data.nFileSizeHigh == 0)
{
write_log("[uploadXML][%d,%d][%s].", data.nFileSizeHigh, data.nFileSizeLow, c_jpgname);
if(data.nFileSizeLow == 0)
{
Sleep(30);
}
else
{
write_log("[uploadXML] 图片异常,存入ERROR目录。");
if(FileExists(pic_error_path + data.cFileName))
{
DeleteFile(pic_error_path + data.cFileName);
}
//图片大小异常,存放到ERROR文件夹
MoveFile((pic_store_path + data.cFileName).c_str(), (pic_error_path + data.cFileName).c_str());
}
continue;
}
这样修改后,那些正常图片就不会放到ERROR目录下了。
不过原因还不是很清晰,感觉这是一个BUG,粘贴出来与大家共享,有不同意见的也可探讨一下。