|
From: jmichae3 on 3 Jul 2008 01:41 I need some working code that walks a directory tree and (at least) prints out the full path of every file. it must work on windows 2000/ xp/vista, and (hopefully) windows 9x. Is there a possibility of getting both dirent.h code for Borland C++ 5.5 and (at the least) win32 code using FindFirstFile/FindNextFile/ FindClose? I have not been able to find any working good examples. Here's what I have: I keep trying, but I never seem to quite get the directory recursion thing down on windows 2000/xp. I get strange results. C:\prj\zapdupes\zapdupes-1.0\win>dir/s/b C:\prj\zapdupes\zapdupes-1.0\win\testdir\a\ C:\prj\zapdupes\zapdupes-1.0\win\testdir\b\ C:\prj\zapdupes\zapdupes-1.0\win\testdir\z C:\prj\zapdupes\zapdupes-1.0\win\testdir\a\a C:\prj\zapdupes\zapdupes-1.0\win\testdir\a\b C:\prj\zapdupes\zapdupes-1.0\win\testdir\a\c C:\prj\zapdupes\zapdupes-1.0\win\testdir\b\a C:\prj\zapdupes\zapdupes-1.0\win\testdir\b\b C:\prj\zapdupes\zapdupes-1.0\win\testdir\b\c C:\prj\zapdupes\zapdupes-1.0\win>zapdupes testdir md5 "testdirz"=d41d8cd98f00b204e9800998ecf8427e C:\prj\zapdupes\zapdupes-1.0\win>zapdupes .\testdir md5 ".\testdirz"=d41d8cd98f00b204e9800998ecf8427e C:\prj\zapdupes\zapdupes-1.0\win>zapdupes c:\prj\zapdupes \zapdupes-1.0\win\testd ir md5 "c:\prj\zapdupes\zapdupes-1.0\win \testdirz"=d41d8cd98f00b204e9800998ecf8427e C:\prj\zapdupes\zapdupes-1.0\win>zapdupes c:\prj\zapdupes \zapdupes-1.0\win\testd ir\ md5 "c:\prj\zapdupes\zapdupes-1.0\win\testdir \z"=ef86d6e78171dddbf5895438933d73f b md5 "c:\prj\zapdupes\zapdupes-1.0\win\testdir\a \a"=3f2349eb8a9c0e80edc08e734b7ef 04b md5 "c:\prj\zapdupes\zapdupes-1.0\win\testdir\a \b"=f1d27b05745dbcd976c488f9730d2 b2a md5 "c:\prj\zapdupes\zapdupes-1.0\win\testdir\a \c"=45a6123cac46f5a8cd432bfad2102 dcd md5 "c:\prj\zapdupes\zapdupes-1.0\win\testdir\b \a"=0de363bdf864da1730f7ebe5a1c59 ff7 md5 "c:\prj\zapdupes\zapdupes-1.0\win\testdir\b \b"=b8d9890b068dce28b17dda5541943 b86 md5 "c:\prj\zapdupes\zapdupes-1.0\win\testdir\b \c"=c5a8a899e66df8c89844d265ca42f cf8 Notice it does not recurse into subdirectories unless the full path is specified and a \ is on the end I thought I took care of that with appendBackslashIfNone. //danger! only use this routine on strings that have enough space // allocated for the extra character! void appendBackslashIfNone(char * str) { int l = strlen(str); if (l > 0 && str[l-1]!='\\') { str[l]='\\'; str[l+1]='\0'; } } //no copyright notice given, but I am putting one here nonetheless. //function Copyright 2000 Michael D. Ober, modified by Jim Michaels void addTreeToList(const char *root, md5list * plist) { HANDLE hRoot; WIN32_FIND_DATA fdRoot; char fRoot[MAX_PATH]; char branch[MAX_PATH]; vector<string> dirs; vector<string>::iterator it; strcpy(fRoot, root); appendBackslashIfNone(fRoot); strcat(fRoot, "*.*"); hRoot = FindFirstFile(fRoot, &fdRoot); if (hRoot == INVALID_HANDLE_VALUE) return; do { strcpy(branch, root); strcat(branch, fdRoot.cFileName); if (fdRoot.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { if ((strcmp(fdRoot.cFileName, ".") != 0) && (strcmp(fdRoot.cFileName, "..") != 0)) { // Subdir found strcat(branch, "\\"); string s=branch; dirs.push_back(s); } } else { // We have a file // printf("DEL: %s\n", branch); // DeleteFile(branch); string s_md5; string s_filepath; s_filepath=branch; // s_filepath=fd.cFileName; //calc md5 printf("md5 \"%s\"=", branch); // printf("md5 \"%s\"=", fd.cFileName); ifstream infile(branch); // ifstream infile(fd.cFileName); //MD5 * md5 = new MD5(); s_md5 = getMD5(infile); printf("%s\n", s_md5.c_str()); //delete md5; //add to list plist->putMd5AndDir(s_md5, s_filepath); } } while (FindNextFile(hRoot, &fdRoot)); FindClose(hRoot); //printf("RD: %s\n", root); //RemoveDirectory(root); for (it=dirs.begin(); it!=dirs.end();it++) { addTreeToList(it->c_str(), plist); } }
From: jmichae3 on 3 Jul 2008 01:52 On Jul 2, 10:41 pm, jmich...(a)yahoo.com wrote: > I need some working code that walks a directory tree and (at least) > prints out the full path of every file. it must work on windows 2000/ > xp/vista, and (hopefully) windows 9x. > > Is there a possibility of getting both dirent.h code for Borland C++ > 5.5 and (at the least) win32 code using FindFirstFile/FindNextFile/ > FindClose? > > I have not been able to find any working good examples. > > Here's what I have: > > I keep trying, but I never seem to quite get the directory recursion > thing down on windows 2000/xp. I get strange results. > C:\prj\zapdupes\zapdupes-1.0\win>dir/s/b > C:\prj\zapdupes\zapdupes-1.0\win\testdir\a\ > C:\prj\zapdupes\zapdupes-1.0\win\testdir\b\ > C:\prj\zapdupes\zapdupes-1.0\win\testdir\z > C:\prj\zapdupes\zapdupes-1.0\win\testdir\a\a > C:\prj\zapdupes\zapdupes-1.0\win\testdir\a\b > C:\prj\zapdupes\zapdupes-1.0\win\testdir\a\c > C:\prj\zapdupes\zapdupes-1.0\win\testdir\b\a > C:\prj\zapdupes\zapdupes-1.0\win\testdir\b\b > C:\prj\zapdupes\zapdupes-1.0\win\testdir\b\c > C:\prj\zapdupes\zapdupes-1.0\win>zapdupes testdir > md5 "testdirz"=d41d8cd98f00b204e9800998ecf8427e > > C:\prj\zapdupes\zapdupes-1.0\win>zapdupes .\testdir > md5 ".\testdirz"=d41d8cd98f00b204e9800998ecf8427e > > C:\prj\zapdupes\zapdupes-1.0\win>zapdupes c:\prj\zapdupes > \zapdupes-1.0\win\testd > ir > md5 "c:\prj\zapdupes\zapdupes-1.0\win > \testdirz"=d41d8cd98f00b204e9800998ecf8427e > > C:\prj\zapdupes\zapdupes-1.0\win>zapdupes c:\prj\zapdupes > \zapdupes-1.0\win\testd > ir\ > md5 "c:\prj\zapdupes\zapdupes-1.0\win\testdir > \z"=ef86d6e78171dddbf5895438933d73f > b > md5 "c:\prj\zapdupes\zapdupes-1.0\win\testdir\a > \a"=3f2349eb8a9c0e80edc08e734b7ef > 04b > md5 "c:\prj\zapdupes\zapdupes-1.0\win\testdir\a > \b"=f1d27b05745dbcd976c488f9730d2 > b2a > md5 "c:\prj\zapdupes\zapdupes-1.0\win\testdir\a > \c"=45a6123cac46f5a8cd432bfad2102 > dcd > md5 "c:\prj\zapdupes\zapdupes-1.0\win\testdir\b > \a"=0de363bdf864da1730f7ebe5a1c59 > ff7 > md5 "c:\prj\zapdupes\zapdupes-1.0\win\testdir\b > \b"=b8d9890b068dce28b17dda5541943 > b86 > md5 "c:\prj\zapdupes\zapdupes-1.0\win\testdir\b > \c"=c5a8a899e66df8c89844d265ca42f > cf8 > > Notice it does not recurse into subdirectories unless the full path is > specified and a \ is on the end I thought I took care of that with > appendBackslashIfNone. > > //danger! only use this routine on strings that have enough space > // allocated for the extra character! > void appendBackslashIfNone(char * str) { > int l = strlen(str); > if (l > 0 && str[l-1]!='\\') { > str[l]='\\'; > str[l+1]='\0'; > } > > } > > //no copyright notice given, but I am putting one here nonetheless. > //function Copyright 2000 Michael D. Ober, modified by Jim Michaels > void addTreeToList(const char *root, md5list * plist) > { > HANDLE hRoot; > WIN32_FIND_DATA fdRoot; > char fRoot[MAX_PATH]; > char branch[MAX_PATH]; > vector<string> dirs; > vector<string>::iterator it; > > strcpy(fRoot, root); > appendBackslashIfNone(fRoot); > strcat(fRoot, "*.*"); > > hRoot = FindFirstFile(fRoot, &fdRoot); > if (hRoot == INVALID_HANDLE_VALUE) > return; > > do { > strcpy(branch, root); > strcat(branch, fdRoot.cFileName); > if (fdRoot.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { > if ((strcmp(fdRoot.cFileName, ".") != 0) && > (strcmp(fdRoot.cFileName, "..") != 0)) { > // Subdir found > strcat(branch, "\\"); > string s=branch; > dirs.push_back(s); > } > } else { // We have a file > // printf("DEL: %s\n", branch); > // DeleteFile(branch); > string s_md5; > string s_filepath; > s_filepath=branch; > // s_filepath=fd.cFileName; > //calc md5 > printf("md5 \"%s\"=", branch); > // printf("md5 \"%s\"=", fd.cFileName); > ifstream infile(branch); > // ifstream infile(fd.cFileName); > //MD5 * md5 = new MD5(); > s_md5 = getMD5(infile); > printf("%s\n", s_md5.c_str()); > //delete md5; > //add to list > plist->putMd5AndDir(s_md5, s_filepath); > } > } while (FindNextFile(hRoot, &fdRoot)); > FindClose(hRoot); > //printf("RD: %s\n", root); > //RemoveDirectory(root); > for (it=dirs.begin(); it!=dirs.end();it++) { > addTreeToList(it->c_str(), plist); > } > > } fixed that code. now on to other bugs. here's the fixed code. //danger! only use this routine on strings that have enough space // allocated for the extra character! void appendBackslashIfNone(char * str) { int l = strlen(str); if (l > 0 && str[l-1]!='\\') { str[l]='\\'; str[l+1]='\0'; } } //no copyright notice given, but I am putting one here nonetheless. //function Copyright 2000 Michael D. Ober, modified by Jim Michaels void addTreeToList(const char *root, md5list * plist) { HANDLE hRoot; WIN32_FIND_DATA fdRoot; char fRoot[MAX_PATH]; char branch[MAX_PATH]; vector<string> dirs; vector<string>::iterator it; strcpy(fRoot, root); appendBackslashIfNone(fRoot); strcat(fRoot, "*.*"); hRoot = FindFirstFile(fRoot, &fdRoot); if (hRoot == INVALID_HANDLE_VALUE) return; do { strcpy(branch, root); appendBackslashIfNone(branch); strcat(branch, fdRoot.cFileName); if (fdRoot.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { if ((strcmp(fdRoot.cFileName, ".") != 0) && (strcmp(fdRoot.cFileName, "..") != 0)) { // Subdir found strcat(branch, "\\"); string s=branch; dirs.push_back(s); } } else { // We have a file // printf("DEL: %s\n", branch); // DeleteFile(branch); string s_md5; string s_filepath; s_filepath=branch; // s_filepath=fd.cFileName; //calc md5 printf("md5 \"%s\"=", branch); // printf("md5 \"%s\"=", fd.cFileName); ifstream infile(branch); // ifstream infile(fd.cFileName); //MD5 * md5 = new MD5(); s_md5 = getMD5(infile); printf("%s\n", s_md5.c_str()); //delete md5; //add to list plist->putMd5AndDir(s_md5, s_filepath); } } while (FindNextFile(hRoot, &fdRoot)); FindClose(hRoot); //printf("RD: %s\n", root); //RemoveDirectory(root); for (it=dirs.begin(); it!=dirs.end();it++) { addTreeToList(it->c_str(), plist); } }
From: jmichae3 on 3 Jul 2008 04:49 well, I have windows code, still need dirent code for Borland C++ 5.5. codegear.com has nothing on their site about this subject. search for opendir and see what happens. nothing.
From: Christian ASTOR on 3 Jul 2008 08:23 On 3 juil, 07:41, jmich...(a)yahoo.com wrote: > I need some working code that walks a directory tree and (at least) > prints out the full path of every file. it must work on windows 2000/ > xp/vista, and (hopefully) windows 9x. e.g. => (I didn't display full path, because it's not very readable) ... (#define UNICODE) WalkDir(L"C:\\foo"); ... DWORD WalkDir(WCHAR *pwszDir) { DWORD dwError = ERROR_SUCCESS; WIN32_FIND_DATA fd; HANDLE hFile; WCHAR szPath[MAX_PATH], szFileName[MAX_PATH]; lstrcpy (szPath, pwszDir); lstrcat (szPath, TEXT("\\*.*")); hFile = FindFirstFile((LPCWSTR)szPath, &fd); if (hFile != INVALID_HANDLE_VALUE) { wprintf(L"Directory : %s\n", pwszDir); do { lstrcpy (szFileName, fd.cFileName); if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) lstrcat (szFileName, TEXT(" <DIR>")); wprintf(L"%s\n", szFileName); } while (FindNextFile(hFile, &fd)); } FindClose(hFile); hFile = FindFirstFile((LPCWSTR)szPath, &fd); if (hFile != INVALID_HANDLE_VALUE) { do { if (!lstrcmp(fd.cFileName, L".") || !lstrcmp(fd.cFileName, L"..")) continue; lstrcpy (szPath, pwszDir); lstrcat (szPath, TEXT("\\")); lstrcat (szPath, fd.cFileName); if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { if (fd.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) continue; dwError = WalkDir(szPath); if (dwError != ERROR_SUCCESS) { FindClose(hFile); return dwError; } } } while (FindNextFile(hFile, &fd)); } FindClose(hFile); return dwError; }
From: Jerry Coffin on 3 Jul 2008 10:01 In article <fe2fdd76-60e1-4d8b-828d- f3d639ba4afb(a)q24g2000prf.googlegroups.com>, jmichae3(a)yahoo.com says... > I need some working code that walks a directory tree and (at least) > prints out the full path of every file. it must work on windows 2000/ > xp/vista, and (hopefully) windows 9x. > > Is there a possibility of getting both dirent.h code for Borland C++ > 5.5 and (at the least) win32 code using FindFirstFile/FindNextFile/ > FindClose? > > I have not been able to find any working good examples. Here's how I do it. This is a bit different from most in doing a breadth-first instead of depth-first traversal. Sometimes it helps quite a bit, others it makes almost no difference (but it's rarely if ever any slower than a depth-first traversal). A queue would work fine where I've used a priority_queue, but this way the output is always sorted. #pragma warning(disable:4786) #include <windows.h> #include <queue> #include <sstream> #include <iostream> #include <algorithm> // I think MS's names for some things are obnoxious. const HANDLE HNULL = INVALID_HANDLE_VALUE; const int A_DIR = FILE_ATTRIBUTE_DIRECTORY; void process(std::string name) { std::cout << name << std::endl; } void PrintFolder(std::string const &folder_name, std::string const &fmask) { HANDLE finder; // for FindFirstFile WIN32_FIND_DATA file; // data about current file. std::priority_queue<std::string, std::vector<std::string>, std::greater<std::string> > dirs; dirs.push(folder_name); // start with passed directory do { std::string path = dirs.top();// retrieve directory to search dirs.pop(); if (path[path.size()-1] != '\\') // normalize the name. path += "\\"; std::string mask = path + fmask; // create mask for searching // traverse a directory. if (HNULL==(finder=FindFirstFile(mask.c_str(), &file))) { continue; } do { if (!(file.dwFileAttributes & A_DIR)) // print file names process(path + file.cFileName); } while (FindNextFile(finder, &file)); FindClose(finder); if (HNULL==(finder=FindFirstFile((path + "*").c_str(), &file))) continue; do { if ((file.dwFileAttributes & A_DIR) && (file.cFileName[0] != '.')) { dirs.push(path + file.cFileName); } } while (FindNextFile(finder, &file)); FindClose(finder); } while (!dirs.empty()); } int main() { PrintFolder("C:\\", "*"); return 0; } -- Later, Jerry. The universe is a figment of its own imagination.
|
Pages: 1 Prev: A problem with a small error Next: get a window not a console |