debug error,DAMAGE: after normal block (#55) at 0x.......
这个错误。我测试的时候,目录深度达到10级,待查找到差不多7/8千个文件的时候会提示上面的这个错误。
我不知该怎么改进这个程序了,或者,根本我的设计思路不太合理,请求达人给予指导。
完成后我会贴出所有的代码。
我设计这个小程序的主要用途为以下几点:
(1)能够遍历指定目录及其子目录下的所有文件,获取文件的修改时间;
(2)将获取到的文件的绝对路径输出到指定的文件中;
(3)能过滤指定的类型的文件;
(4)能过滤指定的文件夹;
当然,我看了DOS下的dir命令足以实现上面的这些要求,但是在我实现我的这个小程序之前,我还没意识使用DOS命令,既然已经做出来了,就干脆完善它。
/**************************************************************
** 这个函数用于输出某个文件的绝对路径名。本函数会发生重入。
** pparent : 上一级路径名,如"D:\\TestDir\\dir-A"
** pself : 当前文件夹名,如"dir-B"
** pfileflt : 过滤文件类型,如"*.mp3;*.mp4;*.obj"
** fileopposite : 是否只查找pfileflt以外的所有文件
** pfldflt : 过滤文件夹,如"folderA;folderB;"
** fldopposite : 是否只查找pfldflt以外的所有文件夹
** pout : 输出文件,文件句柄
** ref : 参考类型,即是否比给定的时间新或旧
*/
static void GetFileFullPathName(char *pparent, char *pself,
char *pfileflt, int fileopposite,
char *pfldflt, int fldopposite,
FILE *pout,
FILE_COMPARE_TYPE ref)
{
FINDDATA_T finddata;
long findhandle = INVALID_HANDLE;
char *tobefind = NULL;
int leng = 0;
leng = strlen(pparent) + 3;
if(pself != NULL)
leng += strlen(pself);
/*这里使用malloc申请内存,而且使用free释放内存,需要注意的是,这个函数时递归调用的,
**系统执行时可能会不断的申请内存,如果申请的内存过小,会导致运行时出错:
**debug error,DAMAGE: after normal block (#55) at 0x.......
**适当增大malloc的内存,可以解决这个问题。
**当然这个问题也可能是由于使用strcat这类的函数导致了数组越界,内存溢出而引发的。
*/
leng = leng > FILE_NAME_STRING_LENGTH ? leng : FILE_NAME_STRING_LENGTH;
tobefind = (char*)malloc(leng);
if(tobefind != NULL)
{
memset((void*)tobefind, 0, leng);
if(pself == NULL)
sprintf(tobefind, "%s\\*.*", pparent);
else
sprintf(tobefind, "%s\\%s\\*.*", pparent, pself);
findhandle = _findfirst(tobefind, &finddata);
if(findhandle != INVALID_HANDLE)
{
while(1)
{
if((finddata.attrib & _A_SUBDIR) && (finddata.name[0] != '.'))
{
memset((void*)tobefind, 0, leng);
if(pself == NULL)
sprintf(tobefind, "%s", pparent);
else
sprintf(tobefind, "%s\\%s", pparent, pself);
if(fldopposite ^ IsCurrentFolderNameFit(pfldflt, finddata.name))
{
//这里开始递归调用
GetFileFullPathName(tobefind,
finddata.name[0]=='\0'?NULL:finddata.name,
pfileflt,
fileopposite,
pfldflt,
fldopposite,
pout,
ref);
}
}
else if(!(finddata.attrib & _A_SUBDIR))
{
if(fileopposite ^ IsCurrentFileExtendNameFit(pfileflt, finddata.name))
{
if(pself == NULL)
{
//是否记录当前文件的绝对路径
if(pout != NULL && IsRecordFilePathFullName(finddata.time_write, file_time_ref, ref))
{
fprintf(pout, "%s\\%s\r\n", pparent, finddata.name);
}
}
else
{
//是否记录当前文件的绝对路径
if(pout != NULL && IsRecordFilePathFullName(finddata.time_write, file_time_ref, ref))
{
fprintf(pout, "%s\\%s\\%s\r\n", pparent, pself, finddata.name);
}
}
}
}
if(_findnext(findhandle, &finddata) == INVALID_HANDLE)
break;
}
_findclose(findhandle);
}
free(tobefind);
}
}
10 个解决方案
#1
众所周知,微软的文件系统经历了 fat->fat32->NTFS 的技术变革。且不论安全和文件组织方式上的革新,单就文件名而言,已经从古老的 DOS 8.3 文件格式(仅支持最长 8 个字符的文件名和 3 个字符的后缀名)转变为可以支持长达 255 个字符的文件名。而对于路径长度,NTFS 也已经支持长达 32768 个字符的路径名。
然而,Windows 操作系统并没有完全放开路径名长度的限制,在 windef.h 中,可以找到如下的宏:
#define MAX_PATH 260
事实上,所有的 Windows API 都遵循这个限制。因此,每当我们试图更改某一文件的文件名时,当输入的文件名长度 ( 全路径 ) 到达一定限度时,虽然文件名本身还未达到 255 个字符的限制,但是任何输入将不再被接受,这其实正是由于操作系统不允许 260 个字符(byte)的文件全路径。
转载地址:http://www.ibm.com/developerworks/cn/java/j-lo-longpath.html
然而,Windows 操作系统并没有完全放开路径名长度的限制,在 windef.h 中,可以找到如下的宏:
#define MAX_PATH 260
事实上,所有的 Windows API 都遵循这个限制。因此,每当我们试图更改某一文件的文件名时,当输入的文件名长度 ( 全路径 ) 到达一定限度时,虽然文件名本身还未达到 255 个字符的限制,但是任何输入将不再被接受,这其实正是由于操作系统不允许 260 个字符(byte)的文件全路径。
转载地址:http://www.ibm.com/developerworks/cn/java/j-lo-longpath.html
#2
学习了,不知道Linux的有没有限制 ,限制又在哪里
#3
#4
#5
栈溢出了吧
#6
递归调用的时候都会压到栈里面去的,文件一多,递归深度太高了的话会爆栈的;
我看程序应该没什么大问题,可能就是这个原因了;
如果能不用递归最好不要用递归的形式写;
很容易出错的;
我看程序应该没什么大问题,可能就是这个原因了;
如果能不用递归最好不要用递归的形式写;
很容易出错的;
#7
system("dir /b /s /a-d D:\\TestDir\\dir-A\\*.* >d:\\allfiles.txt");
//然后读文件d:\\allfiles.txt的内容即D:\\TestDir\\dir-A目录下所有文件的绝对路径
请记住,能用shell命令获取文件、文件夹信息或者操作文件、文件夹最好用shell命令获取或者操作,而不要用各种API获取或者操作,因为当遇到非法文件夹名或非法文件名或非法文件长度、非法文件日期、压缩文件、链接文件、稀疏文件……等各种意料之外的情况时,API会处理的不全面或陷入死循环,而shell命令不会。
//然后读文件d:\\allfiles.txt的内容即D:\\TestDir\\dir-A目录下所有文件的绝对路径
请记住,能用shell命令获取文件、文件夹信息或者操作文件、文件夹最好用shell命令获取或者操作,而不要用各种API获取或者操作,因为当遇到非法文件夹名或非法文件名或非法文件长度、非法文件日期、压缩文件、链接文件、稀疏文件……等各种意料之外的情况时,API会处理的不全面或陷入死循环,而shell命令不会。
#8
计算机组成原理→
DOS命令→汇编语言→C语言(不包括C++)、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言(包括C++)、架构……
#9
楼上各位说的都有道理,看来,如果我要用C语言自己来实现的话,还是有点难度.但是,谁能告诉我,如果不用递归的话,是否还有其他的方法来实现呢?
zhao4zhong1 在8楼说的,应该是一个学习的流程吧?感谢你的建议!
zhao4zhong1 在8楼说的,应该是一个学习的流程吧?感谢你的建议!
#10
如果不用递归是可以的,关于深搜,有两种写法,递归和非递归,递归简单好理解,但是速度慢,要压栈什么的,搞不好还容易出错,非递归的写法稍微复杂点,可以查下深搜非递归写法;
#1
众所周知,微软的文件系统经历了 fat->fat32->NTFS 的技术变革。且不论安全和文件组织方式上的革新,单就文件名而言,已经从古老的 DOS 8.3 文件格式(仅支持最长 8 个字符的文件名和 3 个字符的后缀名)转变为可以支持长达 255 个字符的文件名。而对于路径长度,NTFS 也已经支持长达 32768 个字符的路径名。
然而,Windows 操作系统并没有完全放开路径名长度的限制,在 windef.h 中,可以找到如下的宏:
#define MAX_PATH 260
事实上,所有的 Windows API 都遵循这个限制。因此,每当我们试图更改某一文件的文件名时,当输入的文件名长度 ( 全路径 ) 到达一定限度时,虽然文件名本身还未达到 255 个字符的限制,但是任何输入将不再被接受,这其实正是由于操作系统不允许 260 个字符(byte)的文件全路径。
转载地址:http://www.ibm.com/developerworks/cn/java/j-lo-longpath.html
然而,Windows 操作系统并没有完全放开路径名长度的限制,在 windef.h 中,可以找到如下的宏:
#define MAX_PATH 260
事实上,所有的 Windows API 都遵循这个限制。因此,每当我们试图更改某一文件的文件名时,当输入的文件名长度 ( 全路径 ) 到达一定限度时,虽然文件名本身还未达到 255 个字符的限制,但是任何输入将不再被接受,这其实正是由于操作系统不允许 260 个字符(byte)的文件全路径。
转载地址:http://www.ibm.com/developerworks/cn/java/j-lo-longpath.html
#2
学习了,不知道Linux的有没有限制 ,限制又在哪里
#3
#4
#5
栈溢出了吧
#6
递归调用的时候都会压到栈里面去的,文件一多,递归深度太高了的话会爆栈的;
我看程序应该没什么大问题,可能就是这个原因了;
如果能不用递归最好不要用递归的形式写;
很容易出错的;
我看程序应该没什么大问题,可能就是这个原因了;
如果能不用递归最好不要用递归的形式写;
很容易出错的;
#7
system("dir /b /s /a-d D:\\TestDir\\dir-A\\*.* >d:\\allfiles.txt");
//然后读文件d:\\allfiles.txt的内容即D:\\TestDir\\dir-A目录下所有文件的绝对路径
请记住,能用shell命令获取文件、文件夹信息或者操作文件、文件夹最好用shell命令获取或者操作,而不要用各种API获取或者操作,因为当遇到非法文件夹名或非法文件名或非法文件长度、非法文件日期、压缩文件、链接文件、稀疏文件……等各种意料之外的情况时,API会处理的不全面或陷入死循环,而shell命令不会。
//然后读文件d:\\allfiles.txt的内容即D:\\TestDir\\dir-A目录下所有文件的绝对路径
请记住,能用shell命令获取文件、文件夹信息或者操作文件、文件夹最好用shell命令获取或者操作,而不要用各种API获取或者操作,因为当遇到非法文件夹名或非法文件名或非法文件长度、非法文件日期、压缩文件、链接文件、稀疏文件……等各种意料之外的情况时,API会处理的不全面或陷入死循环,而shell命令不会。
#8
计算机组成原理→
DOS命令→汇编语言→C语言(不包括C++)、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言(包括C++)、架构……
#9
楼上各位说的都有道理,看来,如果我要用C语言自己来实现的话,还是有点难度.但是,谁能告诉我,如果不用递归的话,是否还有其他的方法来实现呢?
zhao4zhong1 在8楼说的,应该是一个学习的流程吧?感谢你的建议!
zhao4zhong1 在8楼说的,应该是一个学习的流程吧?感谢你的建议!
#10
如果不用递归是可以的,关于深搜,有两种写法,递归和非递归,递归简单好理解,但是速度慢,要压栈什么的,搞不好还容易出错,非递归的写法稍微复杂点,可以查下深搜非递归写法;