用CFileFind遍历文件夹,中文子目录读不出来?

misa98 2018-04-07 03:13:39

用CFileFind采用递归方法,遍历当前目录下的所有文件,
但是一个中文的子目录竟然读不出来!我把这个子目录改成英语,马上就读出来了!
这是怎么回事?这不会是MFC的一个bug吧?求解释:
...全文
536 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
你咋这么皮 2020-05-11
  • 打赏
  • 举报
回复
引用 7 楼 赵4老师 的回复:
system("dir /b /a-d c:\\*.* >d:\\allfiles.txt"); //读文件d:\\allfiles.txt的内容即C:\\下所有文件的名字 system("dir /b /a-d /s c:\\*.* >d:\\allfilesinsub.txt"); //读文件d:\\allfilesinsub.txt的内容即C:\\下所有文件的名字包含子目录 system("dir /b /ad c:\\*.* >d:\\alldirs.txt"); //读文件d:\\alldirs.txt的内容即C:\\下所有子目录的名字 请记住,能用shell命令获取文件、文件夹信息或者操作文件、文件夹最好用shell命令获取或者操作,而不要用各种API获取或者操作,因为当遇到非法文件夹名或非法文件名或非法文件长度、非法文件日期、压缩文件、链接文件、稀疏文件……等各种意料之外的情况时,API会处理的不全面或陷入死循环,而shell命令不会。 如果嫌system黑窗口一闪,将system("...")替换为WinExec("cmd /c ...",SW_HIDE);
不愧是大佬啊,尝试了有效,问题是现在是不是又得把这个文件里的内容再读出来??我要的是里面的数据啊...求大佬指点
schlafenhamster 2018-04-08
  • 打赏
  • 举报
回复
或者 ”D:篮球“ 这样的文件名 是 不 合法 的 ‘:‘ 是 特殊 字符 。
赵4老师 2018-04-08
  • 打赏
  • 举报
回复
system("dir /b /a-d c:\\*.* >d:\\allfiles.txt"); //读文件d:\\allfiles.txt的内容即C:\\下所有文件的名字 system("dir /b /a-d /s c:\\*.* >d:\\allfilesinsub.txt"); //读文件d:\\allfilesinsub.txt的内容即C:\\下所有文件的名字包含子目录 system("dir /b /ad c:\\*.* >d:\\alldirs.txt"); //读文件d:\\alldirs.txt的内容即C:\\下所有子目录的名字 请记住,能用shell命令获取文件、文件夹信息或者操作文件、文件夹最好用shell命令获取或者操作,而不要用各种API获取或者操作,因为当遇到非法文件夹名或非法文件名或非法文件长度、非法文件日期、压缩文件、链接文件、稀疏文件……等各种意料之外的情况时,API会处理的不全面或陷入死循环,而shell命令不会。 如果嫌system黑窗口一闪,将system("...")替换为WinExec("cmd /c ...",SW_HIDE);
schlafenhamster 2018-04-08
  • 打赏
  • 举报
回复
“D:篮球” 不存在 , 应该是 D:\篮球
zgl7903 2018-04-08
  • 打赏
  • 举报
回复
标准WIN32的

  HANDLE hSearch;
  WIN32_FIND_DATA FindData;
  TCHAR szFile[MAX_PATH + 1];  
  
  hSearch = FindFirstFile(_T("*.*"), &FindData);
  if (INVALID_HANDLE_VALUE != hSearch) 
  {
    do
    {
      _tfullpath(szFile, FindData.cFileName, MAX_PATH);
      TRACE(_T("%s\n"), szFile);
    } while (FindNextFile(hSearch, &FindData));
    
    FindClose(hSearch);
  }
再看MFCCFileFind的实现源码

//FILEFIND.CPP
BOOL CFileFind::FindFile(LPCTSTR pstrName /* = NULL */,
	DWORD dwUnused /* = 0 */)
{
        ……
	Close();
	m_pNextInfo = new WIN32_FIND_DATA;
        ……    	
	m_hContext = ::FindFirstFile(pstrName, (WIN32_FIND_DATA*) m_pNextInfo);
        ……
}

BOOL CFileFind::FindNextFile()
{
	ASSERT(m_hContext != NULL);

	if (m_hContext == NULL)
		return FALSE;
	if (m_pFoundInfo == NULL)
		m_pFoundInfo = new WIN32_FIND_DATA;

	ASSERT_VALID(this);

	void* pTemp = m_pFoundInfo;
	m_pFoundInfo = m_pNextInfo;
	m_pNextInfo = pTemp;

	return ::FindNextFile(m_hContext, (LPWIN32_FIND_DATA) m_pNextInfo);
}
而CFileFind 类的与路径返回的都是基于m_pFoundInfo, 因此可以看出 CFileFind::FindNextFile() 中使用的是上次的搜索结果 因此上面等效的MFC的代码就是

  CFileFind finder;
  BOOL bWorking = finder.FindFile("*.*");
  while (bWorking)
  {
    bWorking = finder.FindNextFile();
    TRACE(_T("%s\n"), finder.GetFilePath());
  }
zgl7903 2018-04-08
  • 打赏
  • 举报
回复
是否是文件分隔符 与转义符的问题? ‘\\' '\n' _T("D:\\Path\\*.*")
misa98 2018-04-08
  • 打赏
  • 举报
回复
还有一个问题一直困扰着我,为什么不是: CFileFind find; find.FindFile(path); CString str=find.GetFilePath(); find.FindNextFile; 为什么程序必须在执行完FindNextFile之后,才能GetFilePath? 为什么不是在FindFile之后,GetFilePath? ;这样似乎把第一个文件给跳过去了?
schlafenhamster 2018-04-08
  • 打赏
  • 举报
回复
"为什么D:篮球里的文件读不出来呢?" 还是“”D:篮球“”读不出来呢?
misa98 2018-04-08
  • 打赏
  • 举报
回复
我的程序就是把当前目录下的文件都写到一个文本文件中。比如D:篮球,这个子目录下的文件就读不出来, 如果我把它改成英语,比如D:ball,文件马上就读出来了。 当然,D:盘下的其他中文子目录也能读出来。为什么D:篮球里的文件读不出来呢? 是不是因为这个中文子目录里的文件比较多呀,有2000多个文件。 即便如此,这不也是MFC的一个BUG吗? 为什么我把中文的子目录改成英文的,文件马上就读出来了?
schlafenhamster 2018-04-08
  • 打赏
  • 举报
回复
BOOL bFound=find.FindFile(FilePath); 这个结果 要 保存 , 否则 递归时 会 改变 !
schlafenhamster 2018-04-08
  • 打赏
  • 举报
回复
有 漏的 !

//
void CDirDDlg::Find(CString FilePath)
{
	CFileFind find;
	BOOL bFound=find.FindFile(FilePath);
	while (bFound) 
	{
		bFound=find.FindNextFile();
		CString text=find.GetFilePath();
		afxDump << text << "\n";
		if(find.IsDirectory())
		{
			if(!find.IsDots())
			{
				text+="\\*.*";
				Find(text);	//进行函数的递归调用
			}
		}
		else
		{
			text+="\r\n";
			m_file.Write(text,text.GetLength());
			m_count++;
		}
	}
}

void CDirDDlg::OnButton1() 
{
	// TODO: Add your control notification handler code here
	m_count=0;
	char buf[512];
	::GetCurrentDirectory(512,buf);
	
	strcat(buf,"\\*.*");
	m_file.Open("FIND.txt",CFile::modeCreate|CFile::modeReadWrite);
//
	Find(buf);
//
	m_file.Close(); //记着关闭文件
//
	CString str;
	str.Format("文件总数为%d",m_count);
	MessageBox(str);
	
}
misa98 2018-04-08
  • 打赏
  • 举报
回复
程序很简单,同学们帮我看看哪写错了? void CMyDlg::Find(CString FilePath) { CFileFind find; find.FindFile(FilePath); while(find.FindNextFile()) { CString text=find.GetFilePath(); if(find.IsDirectory()) { if(!find.IsDots()) { text+="\\*.*"; Find(text); //进行函数的递归调用 } } else { text+="\n"; file.Write(text,text.GetLength()); count++; } } } void CMyDlg::OnButton1() { // TODO: Add your control notification handler code here char buf[512]; ::GetCurrentDirectory(512,buf); strcat(buf,"\\*.*"); file.Open("FIND.txt",CFile::modeCreate|CFile::modeReadWrite); Find(buf); file.Close(); //记着关闭文件 CString str; str.Format("文件总数为%d",count); MessageBox(str); }
misa98 2018-04-08
  • 打赏
  • 举报
回复
篮球是D:盘上的一个子目录,目录名怎么可能不合法呢?不合法Windows能让篮球存在D盘上? 我用CFileFind的GetFilePath获取的文件或文件夹名,怎么可能出错呢? 有同学可能怀疑是不是我程序写的有问题? 问题是我把D:盘上的篮球改成随便一个英语名,篮球里的文件马上就读出来了! 我不知道这是不是MFC的一个bug,反正我是碰到这种情况了。
etz2008 2018-04-07
  • 打赏
  • 举报
回复
没这个BUG,中文应该也能读出来
schlafenhamster 2018-04-07
  • 打赏
  • 举报
回复
给个例子

////////////////////////////////////////////////////////////////////
void CDirTreeCtrl::DisplayPath(HTREEITEM hParent, LPCTSTR strPath)
{// Displaying the Path in the TreeCtrl
	CFileFind find;
	CString   strPathFiles = strPath;
	BOOL      bFind;
	CSortStringArray strDirArray;
	CSortStringArray strFileArray;
	
	if ( strPathFiles.Right(1) != "\\" ) strPathFiles += "\\";
	strPathFiles += "*.*";

	bFind = find.FindFile( strPathFiles );

	while ( bFind )
	{
		bFind = find.FindNextFile();
		if ( find.IsDirectory() && !find.IsDots() )
		{		
			strDirArray.Add( find.GetFilePath() );
		}
		if ( !find.IsDirectory() && m_bFiles ) strFileArray.Add( find.GetFilePath() );
	}
    
	strDirArray.Sort();
//
	SetRedraw(FALSE);
	CWaitCursor wait;
    
	for ( int i = 0; i < strDirArray.GetSize(); i++ )
	{
			HTREEITEM hItem = AddItem( hParent, strDirArray.GetAt(i) );
			if(FindSubDir(strDirArray.GetAt(i))) InsertItem("", 0, 0, hItem);
	}

	if ( m_bFiles )
	{
		strFileArray.Sort();
		for ( i = 0; i < strFileArray.GetSize(); i++ )
		{
			HTREEITEM hItem = AddItem( hParent, strFileArray.GetAt(i) );
		}
	}
	SetRedraw(TRUE);
//
}

16,472

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

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