关于FindFirst查找到不匹配文件的问题

yxdm 2008-04-08 02:19:37
本人编写一段代码,目的是从一个包含50000多个文件的文件夹中将一些特定的文件copy到一个指定的目录。
使用
for(int i=0;i<50;i++)
FindFirst(Path,faAnyFile,sr);
其中path=StrPath+"\\"+AnsiString(i)+"_C*.jpg"
目的是找到所有"i_C*_*_*.jpg"(i为1到50)
出现问题的现象:
1. 找到了4_L18*_*.jpg(错误)
2. 其他不匹配的文件"N_G*.jpg"等没有找到(理想情况)
3. 所有"N_C*.jpg"都找到了(理想情况)
测试:
1. 令path=StrPath+"\\"+AnsiString(i)+"_L*.jpg"
执行结果将所有"N_L*.jpg"都找到了(正常);
2. 将所有1~50开头的文件手工复制到一个新文件夹;(文件个数减少)
执行该程序,则不会找到4_L18*_*.jpg;(正常)
临时解决方案:
找到sr后,查找sr.Name中"N_C"的位置,如果不匹配则放弃。则运行结果正常。

请有经验的朋友帮忙解释一下出错原因。(我感觉像是文件过多的原因,但是不知道出错机理)
...全文
93 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
yxdm 2008-04-08
  • 打赏
  • 举报
回复
if(sr.Name.Pos(AnsiString(i)+"_C")==1)
加了这个判断确实就不再出错了,但总觉得应该找到出错的原因。
感谢helenhf的热心参与。
helenhf 2008-04-08
  • 打赏
  • 举报
回复
实在不行就在sr.Name中间加个判断好了~
yxdm 2008-04-08
  • 打赏
  • 举报
回复
首贴中的测试:
2. 将所有1~50开头的文件手工复制到一个新文件夹;(文件个数减少)
执行该程序,则不会找到4_L18*_*.jpg;(正常)
就是将出错的文件放到别的目录,在用该程序去copy到另一个目录,则不出错。

所以我怀疑是文件夹中文件过多引起的,但没找到相关证据(网上)。
有些懒得做测试(可以将文件夹中文件先删除后面一半,出错则继续删,不出错则补上,似可找到文件个数限制)。
helenhf 2008-04-08
  • 打赏
  • 举报
回复
“而且在文件夹中文件数目较少的情况下并没有问题。”

文件夹数目较少的情况下,有没有把那几个错误的测试用例拿过来试试,能不能重现?
yxdm 2008-04-08
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 ydlchina 的回复:]
老哥 难道你参照我的代码看不出你的问题,每次循环你始终是只是查的文件夹的第一个文件,其它文件当然查不到了,循环内有循环,仔细推敲一下代码,注意里面那个循环
[/Quote]
感谢9楼helenhf的理解。
to ydlchina:
感谢您的热心答复。我的问题不是找不全同类文件(我的代码是为了更清晰地阐述问题,将问题简化成每类文件只有一个,所以不用FindNext),而是找到了错误的文件.
可惜的是朋友们很难复现该错误(需要有个包含50000多文件的文件夹),而且也只是找4_C*.jpg时找到了4_L1834_2_0.jpg,而找其他的诸如8_C*.jpg时并没有把8_L1*.jpg找出来。而且在文件夹中文件数目较少的情况下并没有问题。
不知道是否有朋友遇到过类似问题,或在哪里见到过有关这方面的解释。或者有关使用FindFirst时的文件数目限制方面的介绍。
当然也不排除代码的问题。

我再将需求说明白些
文件是一些物品的照片,文件名是有意义的:第一个"_"左边的数字描述物品的序号,右边在第二个"_"以前的字符串描述物品的类型。程序的任务是将某个序号范围内同一种类型的物品的图片保存到另一个目录下。
helenhf 2008-04-08
  • 打赏
  • 举报
回复
path=StrPath+"\\"+AnsiString(i)+"_C*.jpg";
楼主在这里修改了path的值
相当于改了文件名
所以调用findfirst也没错
ydlchina 2008-04-08
  • 打赏
  • 举报
回复
老哥 难道你参照我的代码看不出你的问题,每次循环你始终是只是查的文件夹的第一个文件,其它文件当然查不到了,循环内有循环,仔细推敲一下代码,注意里面那个循环
yxdm 2008-04-08
  • 打赏
  • 举报
回复
感谢给出完整代码.
我的问题是:在下面代码第4次执行到断点位置时,可看到path="E:\\1\\test\\4_C*.jpg",而sr.Name="4_L1825_2_0.jpg";
明明与我的条件不匹配,为什么还会查找到该文件;
而且这种情况只出现在StrPath指向500000多个文件的文件夹时。

StrPath="E:\\1\\test";
StrNewPath="F:\\图片";
TSearchRec sr;
for(int i=1;i <50;i++)
{
path=StrPath+"\\"+AnsiString(i)+"_C*.jpg";
if(FindFirst(Path,faAnyFile,sr)==0)
{
if(sr.Name.Pos(AnsiString(i)+"_C")==1)//如果没有这个判断则会将4_L18*_*.jpg拷贝出去 //******断点*******
{
拷贝该文件到StrNewPath;
}
FindClose(sr);
}
}
ydlchina 2008-04-08
  • 打赏
  • 举报
回复

void __fastcall TForm2::Button1Click(TObject *Sender)
{
AnsiString Dirpath="C:\\ydlchina";
if(Dirpath[Dirpath.Length()-1] != '\\')
Dirpath = Dirpath + "\\";
TSearchRec sr;
for(int i=0;i<50;i++)
{ //只查找符合 “i_C*.jpg” 规则的文件,如果楼主还需要其它规则
//就需要你重新确定新的规则。
AnsiString path=Dirpath + IntToStr(i) + AnsiString("_C*.jpg");
if(FindFirst(path,faAnyFile,sr)==0)
{
while(1)
{
if(sr.Attr != faDirectory)
{
if(sr.Name !="." && sr.Name!="..")
{
//在此为复制出的文件
ListBox1->Items->Add(Dirpath+sr.Name);
}
}
if(FindNext(sr)!=0) break;
}
}
FindClose(sr);//释放FindFirst()所申请的内存资源
}


}
//---------------------------------------------------------------------------

yxdm 2008-04-08
  • 打赏
  • 举报
回复
回复3楼helenhf:
谢谢提供一个代码。我这里能保证满足条件的文件肯定不是子目录,是否不必加if(!(sr.Attr & faDirectory))?
每次查找的文件Mask随着i的变化是不同的,所以都应该用FindFirst吧?
yxdm 2008-04-08
  • 打赏
  • 举报
回复
代码简单写一下:

StrPath="E:\\1\\test";
StrNewPath="F:\\图片";
TSearchRec sr;
for(int i=0;i<50;i++)
{
path=StrPath+"\\"+AnsiString(i)+"_C*.jpg";
if(FindFirst(Path,faAnyFile,sr)==0)
{
if(sr.Name.Pos(AnsiString(i)+"_C")==1)//如果没有这个判断则会将4_L18*_*.jpg拷贝出去
{
拷贝该文件到StrNewPath;
}
FindClose(sr);
}
}
helenhf 2008-04-08
  • 打赏
  • 举报
回复
// strPath: 路径名
// strfile: 文件名
void SearchFiles(AnsiString strPath, AnsiString strfile, TStrings* Files)
{
TSearchRec sr;

if(strPath[Path.Length()] != '\\') strPath += '\\';
if(FindFirst(strPath + strfile,faAnyFile,sr)) return;
do
{
if(!(sr.Attr & faDirectory)) // 找到的是文件
{
Files->Add(Path+sr.Name);
}
}while(FindNext(sr)==0);
FindClose(sr);
}

helenhf 2008-04-08
  • 打赏
  • 举报
回复
应该是第一次调用FindFirst
以后都调用FindNext函数
ydlchina 2008-04-08
  • 打赏
  • 举报
回复
看看你的代码

604

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder VCL组件使用和开发
社区管理员
  • VCL组件使用和开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧