能力值:
( LV2,RANK:10 )
|
-
-
2 楼
Mark
|
能力值:
( LV2,RANK:10 )
|
-
-
3 楼
do{
wsprintf(fullpath,L"%s\%s\\",dir,d.cFileName);
1. d.cFileName如果是文件,不是文件夹的话,比如1.txt
fullpath就变成C:\1.txt\,实际搜索就变成了C:\1.txt\*.*,所以有问题
2.wsprintf(fullpath,L"%s \%s\\" 这里格式化串犯了常见错误啊 第一个%s后的\%,转移了%
是不对的,应该是 \\%吧
修改建议
do{
if(d.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY){
if(lstrcmp(d.cFileName,L".")==0||lstrcmp(d.cFileName,L"..")==0){
wsprintf(fullpath,L"%s[COLOR="Red"]\\%s[/COLOR]\\",dir,d.cFileName);
//wcout<<d.cFileName<<endl;
wcout<<L"nono"<<endl;
continue;
}
//wcout<<fullpath<<endl;
findAll(fullpath);
}
}while(FindNextFile(fp,&d));
未测试,自己改改看吧
|
能力值:
( LV4,RANK:50 )
|
-
-
4 楼
markmark
|
能力值:
( LV2,RANK:10 )
|
-
-
5 楼
不错 学习了
|
能力值:
( LV2,RANK:10 )
|
-
-
6 楼
你的代码实在是....不工整啊..看了半天...
以下代码在VS2010下测试通过:
#include "stdafx.h"
#include "windows.h"
#include<iostream>
using namespace std;
void findAll(WCHAR *dir){
//打印当前正在检索的路径
wcout<<"检索目录:"<<dir<<endl;
/*初始化变量*/
//当前路径
WCHAR path[256];
//下一搜索路径
WCHAR fullpath[256]=L"";
//搜索文件过滤器
WCHAR *n=L"*.*";
//拼装搜索路径及搜索文件串
lstrcpy(path,dir);
lstrcatW(path,n);
//搜索文件
WIN32_FIND_DATA d;
HANDLE fp=NULL;
fp= FindFirstFile(path,&d);
if(fp==NULL){
wcout<<"打开失败"<<endl;
}
do{
try
{
//如果搜索到的文件是目录
if(d.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY){
//如果目录名称是.或者..则过滤掉
if(lstrcmp(d.cFileName,L".")==0||lstrcmp(d.cFileName,L"..")==0){
continue;
}
else//将目录设置为下一个递归搜索的目录
wsprintf(fullpath,L"%s\\%s\\",dir,d.cFileName);
//搜索目录
findAll(fullpath);
}else //如果搜索到的文件不是目录,则当做文件处理,打印出文件全路径
{
wsprintf(fullpath,L"%s\\%s",dir,d.cFileName);
wcout<<"检索到文件:"<<fullpath<<endl;
}
}catch(...)
{
continue;
}
}while(FindNextFile(fp,&d));
}
int _tmain(int argc, _TCHAR* argv[])
{
findAll(L"c:\\");
return 0;
}
手机上网速度太慢,控制台截图我就不传了.
|
能力值:
( LV2,RANK:10 )
|
-
-
7 楼
学习了...
|
能力值:
( LV2,RANK:10 )
|
-
-
8 楼
看了看,没啥东西啊!!!
|
能力值:
( LV2,RANK:10 )
|
-
-
9 楼
在VS2008下写了个MFC的,用来销毁磁盘文件的,原理就是查找所有文件,找到后向文件中写入等长的数据。文件在磁盘上还是不是原来的扇区就没去研究了。受限于磁盘传输机制,多线程也没什么大作用的,就搞了个单后台线程的,对话框界面不会卡顿。
成品的软件就不贴出来了,光贴出个坯子吧。成品关键代码跟这个一模一样,成品多了一些美化、系统注册及右键菜单、判断磁盘并根据磁盘数量确定工作线程数量是否使用IOCP等非常多的细节问题。
光贴一个主对话框的源文件,熟悉MFC的同学很容易就能完成整个项目。 代码风格么,呵呵了。我比较喜欢这样的风格,因为调试的时候比较容易区分层级。
MFC很多其他东西就不贴了。
部分代码如下:
void TraversFile(CString strPath,LPVOID lpClsDlg,int nID,LPTSTR lpszFillWord,UINT nFillWordCnt,BOOL bSubDirIncld);
LRESULT CFileDestroyerDlg::OnWorkThreadDone(WPARAM wParam,LPARAM lParam)
{
// TODO: 在此添加控件通知处理程序代码
this ->hWorkThread = NULL;
this ->SetDlgItemText(IDC_BUTTON_START,_T("开始"));
::bWorking = false;
return 0;
}
void CFileDestroyerDlg::OnBnClickedCancel()
{
// TODO: 在此添加控件通知处理程序代码
OnCancel();
}
void CFileDestroyerDlg::OnBnClickedButtonStart()
{
// TODO: 在此添加控件通知处理程序代码
if(::bWorking)
{
this ->SetDlgItemText(IDC_BUTTON_START,_T("开始"));
::bWorking = false;
}
else
{
if(IDYES != this ->MessageBox(_T("注意:\n\t本操作会将所有可打开的文件进行复写操作;\n\t本操作会永久性使数据消失;\n\t本操作不可逆;\n\t\t是否继续?"),_T("警告:危险操作"),MB_YESNO | MB_ICONERROR))
{
return;
}
this ->SetDlgItemText(IDC_BUTTON_START,_T("停止"));
::bWorking = true;
if(NULL == (this ->hWorkThread = ::CreateThread(NULL,0,thrdWork,this,0,NULL)))
{
this ->MessageBox(_T("创建工作线程失败!"));
this ->OnBnClickedButtonStart();
}
this ->SetDlgItemText(IDC_STATIC_FINISHCOUNT,_T("0"));
}
}
DWORD WINAPI thrdWork(LPVOID lParam)
{
CFileDestroyerDlg* pDlg = (CFileDestroyerDlg*)lParam;
if(0 == pDlg ->strFilePath.GetLength())
{
return 0;
}
CString strFilePath = pDlg ->strFilePath;
BOOL bSingleFile = pDlg ->bSingleFile;
BOOL bSubDirIncluded = pDlg ->bSubDirIncluded;
UINT nDestroyCount = pDlg ->nDestroyCnt;
UINT nFillWordCntEx = pDlg ->strFillWord.GetLength() * sizeof(TCHAR);
UINT nFillWordCnt = 0;
LPTSTR szFillWord;
if(nFillWordCntEx)
{
nFillWordCnt = nFillWordCntEx;
szFillWord = new TCHAR[1 + nFillWordCnt / sizeof(TCHAR)];
::wsprintf(szFillWord,_T("%s"),pDlg ->strFillWord);
}
else
{
szFillWord = _T("Zkek 文件粉碎机 Contact:775286866@qq.com\n");
CString str = _T("Zkek 文件粉碎机 Contact:775286866@qq.com\n");
nFillWordCnt = str.GetLength() * sizeof(TCHAR);
}
if(bSingleFile)
{
pDlg ->SetDlgItemText(IDC_STATIC_FILEPATH,_T(" 正在粉碎文件: ") + strFilePath);
BYTE* pWrite = (BYTE*)::malloc(50 * 1024 * 1024);
int nFillTimes = 50 * 1024 * 1024 / nFillWordCnt;
for(int i = 0;i < nFillTimes;i++)
{
::memcpy(&pWrite[i * nFillWordCnt],szFillWord,nFillWordCnt);
}
for(UINT i = 0;i < nDestroyCount;i++)
{
CFile FileIn;
if(FileIn.Open(strFilePath,CFile::modeWrite))
{
LONGLONG llFileLength = FileIn.GetLength();
LONGLONG llFillTimesCnt = llFileLength / (50 * 1024 * 1024);
FileIn.SeekToBegin();
for(LONGLONG j = 0; j < llFillTimesCnt;j++)
{
FileIn.Write(pWrite,50 * 1024 * 1024);
}
if(llFileLength - llFillTimesCnt * 50 * 1024 * 1024)
{
FileIn.Write(pWrite,(llFillTimesCnt + 1) * 50 * 1024 * 1024 - llFileLength);
}
FileIn.Flush();
FileIn.Close();
CString str;
str.Format(_T("%d"),i + 1);
pDlg ->SetDlgItemText(IDC_STATIC_FINISHCOUNT,str);
}
if(!::bWorking)
{
break;
}
}
::free(pWrite);
}
else
{
if(0 != strFilePath.Right(1).Compare(_T("\\")))
{
CFile FileIn;
for(UINT i = 0;i < nDestroyCount;i++)
{
if(FileIn.Open(strFilePath,CFile::modeCreate | CFile::modeWrite))
{
FileIn.SeekToBegin();
FileIn.Write(szFillWord,nFillWordCnt);
FileIn.Flush();
FileIn.Close();
}
else
{
CString strPath = pDlg ->strFilePath;
strPath += _T("\\");
for(UINT i = 0;i < nDestroyCount;i++)
{
::TraversFile(strPath,pDlg,IDC_STATIC_FILEPATH,szFillWord,nFillWordCnt,bSubDirIncluded);
CString str;
str.Format(_T("%d"),i + 1);
pDlg ->SetDlgItemText(IDC_STATIC_FINISHCOUNT,str);
}
}
}
}
else
{
for(UINT i = 0;i < nDestroyCount;i++)
{
::TraversFile(strFilePath,pDlg,IDC_STATIC_FILEPATH,szFillWord,nFillWordCnt,bSubDirIncluded);
CString str;
str.Format(_T("%d"),i + 1);
pDlg ->SetDlgItemText(IDC_STATIC_FINISHCOUNT,str);
}
}
}
if(nFillWordCntEx)
{
delete [] szFillWord;
}
if(::bWorking)
{
pDlg ->SetDlgItemText(IDC_STATIC_FILEPATH,strFilePath + _T(" 文件粉碎完成!"));
}
else
{
pDlg ->SetDlgItemText(IDC_STATIC_FILEPATH,strFilePath + _T(" 文件粉碎停止!"));
}
::PostMessage(pDlg ->m_hWnd,WORK_THREAD_DONE,0,0);
return 0;
}
void CFileDestroyerDlg::OnCancel()
{
// TODO: 在此添加专用代码和/或调用基类
if(::bWorking)
{
::bWorking = false;
}
this ->SetDlgItemText(IDC_EDIT_PATH,_T("清理资源..."));
if(this ->hWorkThread)
{
::WaitForSingleObject(this ->hWorkThread,INFINITE);
}
CDialog::OnCancel();
}
void CFileDestroyerDlg::OnOK()
{
// TODO: 在此添加专用代码和/或调用基类
//CDialog::OnOK();
}
void CFileDestroyerDlg::OnBnClickedCheckIncldsubdir()
{
// TODO: 在此添加控件通知处理程序代码
this ->UpdateData();
this ->bSingleFile = false;
this ->UpdateData(FALSE);
}
void TraversFile(CString strPath,LPVOID lpClsDlg,int nID,LPTSTR szFillWord,UINT nFillWordCnt,BOOL bSubDirIncld)
{
CString strPrePath = strPath;
CString strNextPath = strPath;
CFileFind ff;
strPath += _T("*.*");//遍历这一级全部的目录
int nResult = ff.FindFile(strPath);
while(nResult && ::bWorking)
{
nResult = ff.FindNextFileW();
if(ff.IsDirectory())
{
if(bSubDirIncld)
{
if(!ff.IsDots())
{
strNextPath += ff.GetFileName();
strNextPath += _T("\\");
TraversFile(strNextPath,lpClsDlg,nID,szFillWord,nFillWordCnt,bSubDirIncld);
}
}
}
else
{
CFile FileIn;
if(FileIn.Open(ff.GetFilePath(),CFile::modeCreate | CFile::modeWrite))
{
FileIn.SeekToBegin();
FileIn.Write(szFillWord,nFillWordCnt);
FileIn.Flush();
FileIn.Close();
}
}
CFileDestroyerDlg* lpDlg = (CFileDestroyerDlg*)lpClsDlg;
lpDlg ->SetDlgItemText(nID,ff.GetFilePath());
strNextPath = strPrePath;
}
}
void CFileDestroyerDlg::OnBnClickedButtonBrowse()
{
// TODO: 在此添加控件通知处理程序代码
//CZkekFileDialog dlgFile(TRUE,NULL,NULL,OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,NULL,NULL,0,TRUE);
CFileDialog dlgFile(TRUE);
if(IDOK == dlgFile.DoModal())
{
this ->strFilePath = dlgFile.GetPathName();
this ->UpdateData(FALSE);
}
}
我觉得LZ的代码如果调试的话,5分钟就明白为什么了,根本没必要花同样甚至更多时间发帖。。。
|
能力值:
( LV2,RANK:10 )
|
-
-
10 楼
我使用了好多递归遍历的 ,都存在 部分文件无法打印的问题,要么也不会发帖,麻烦
|
能力值:
( LV2,RANK:10 )
|
-
-
11 楼
仅仅是打印?如果是打印字符无法显示的话会不会是ANSI和Unicode问题?试试格式化的时候指定CStringA或者CString和_T("")
|
能力值:
( LV2,RANK:10 )
|
-
-
12 楼
用它来搜索文件 是可以搜到的 ,只是全部打印,,打印一部分就结束了
|
能力值:
( LV2,RANK:10 )
|
-
-
13 楼
哈哈,这种问题最好解决,我却帮不了你。 在你的IDE里下断点调试吧,特别是条件断点,应该很有效。
还有,调试的时候注意观察堆栈情况,防止因为资源不足而退出打印。
各种try catch SEH之类的编程方法也会对你的问题有很大帮助。
TRACE,OutputDebugString之类也是极好的。
|