list - c# How to iterate through the file system and assign numbering -
i have problem doing head in.
i want iterate through local pc folders, including directories, , calculate numbering system against each folder in file system hierarchy.
the root folders should calculate 1,2,3 etc.
if there 3 sub-folders in folder 1 calculated numbers should be: 1.1, 1.2,1.3
if there 3 sub-folders in sub-folder above calculated numbers should be: 1.1.1, 1.1.2, 1.1.3
if there 3 sub-folders in folder 2 (a root folder) calculated numbers should be: 2.1, 2.2, 2.3
or expressed in way:
1 root folder 1.1 root sub folder 1 1.1.1 sub folder 1.1.2 sub folder 1.2 root sub folder 2 1.2.1 list item 1.2.2 list item
etc. etc.
this logic should applied folders , sub-folders.
output example
1.1.1 | "c:\root\folder1\folder1\"
what have far appears work ok in situations can fail in other situations:
private string rootpath = @"c:\folderhierarchy\"; private string foldersequencecountbase = ""; private int currentrootpathcount = 0; private int counter = 0; private void calculatefolderhierarchynumbers() { //get first list of folders string[] dirs = directory.getdirectories(rootpath, "*.*", searchoption.topdirectoryonly); (int = 0; < dirs.count(); i++) { foldersequencecountbase = (i + 1).tostring(); currentrootpathcount = + 1; console.writeline("processed folder '{0}'.", dirs[i] + " = " + (i + 1)); getsubdirs(dirs[i]); } } private void getsubdirs(string item) { //get next list of folders in folder hierarchy string[] subdirs = directory.getdirectories(item, "*.*", searchoption.topdirectoryonly); foreach (var dirpath in subdirs) { //increment count of folders within current folder list counter += 1; console.writeline("processed folder '{0}'.", dirpath + " = " + foldersequencecountbase + "." + counter); } counter = 0; //get next list of folders in folder hierarchy foreach (var dirpath in subdirs) { foldersequencecountbase += ".1"; getsubdirs(dirpath); } }
hope clear.
thanks rick
so want find file , it's number of in of directory , of it's parent directories? since found interesting i've written scratch. note it's not tested might give idea anyway:
public static ienumerable<fileentryinfo> enumeratefindfiles(string filetofind, stringcomparison comparison = stringcomparison.currentcultureignorecase, directoryinfo rootdir = null, string[] drivestosearch = null) { ienumerable<fileentryinfo> foundentries = enumerable.empty<fileentryinfo>(); if (rootdir != null && drivestosearch != null) throw new argumentexception("specify either root-dir or drives search, not both"); else if (rootdir != null) { foundentries = enumeratefindentryroot(filetofind, rootdir, comparison); } else { if (drivestosearch == null) // search entire computer drivestosearch = system.environment.getlogicaldrives(); foreach (string dr in drivestosearch) { system.io.driveinfo di = new system.io.driveinfo(dr); if (!di.isready) { console.writeline("the drive {0} not read", di.name); continue; } rootdir = di.rootdirectory; foundentries = foundentries.concat(enumeratefindentryroot(filetofind, rootdir, comparison)); } } foreach (fileentryinfo entry in foundentries) yield return entry; } public class fileentryinfo { public fileentryinfo(string path, int number) { this.path = path; this.number = number; } public int number { get; set; } public string path { get; set; } public fileentryinfo root { get; set; } public ienumerable<int> getnumbertree() { stack<fileentryinfo> filo = new stack<fileentryinfo>(); fileentryinfo entry = this; while (entry.root != null) { filo.push(entry.root); entry = entry.root; } while(filo.count > 0) yield return filo.pop().number; yield return this.number; } public override bool equals(object obj) { fileentryinfo fei = obj fileentryinfo; if(obj == null) return false; return number == fei.number && path == fei.path; } public override int gethashcode() { return path.gethashcode(); } public override string tostring() { return path; } } private static ienumerable<fileentryinfo> enumeratefindentryroot(string filenametofind, directoryinfo rootdir, stringcomparison comparison = stringcomparison.currentcultureignorecase) { queue<fileentryinfo> queue = new queue<fileentryinfo>(); fileentryinfo root = new fileentryinfo(rootdir.fullname, 1); queue.enqueue(root); while (queue.count > 0) { fileentryinfo fe = queue.dequeue(); list<fileentryinfo> validfiles = new list<fileentryinfo>(); try { // cannot yield try-catch, hence approach fileattributes attr = file.getattributes(fe.path); //detect whether directory or file bool isdirectory = (attr & fileattributes.directory) == fileattributes.directory; if (isdirectory) { int entrycount = 0; foreach (string entry in directory.enumeratefilesystementries(fe.path)) { entrycount++; fileentryinfo subentry = new fileentryinfo(entry, entrycount); subentry.root = fe; queue.enqueue(subentry); attr = file.getattributes(entry); isdirectory = (attr & fileattributes.directory) == fileattributes.directory; if(!isdirectory) validfiles.add(subentry); } } } catch (exception ex) { console.error.writeline(ex); // ignore, proceed } foreach (fileentryinfo entry in validfiles) { string filename = path.getfilename(entry.path); if (filename.equals(filenametofind, comparison)) yield return entry; } } }
here's how tested it:
var allentriesfound = enumeratefindfiles("presentationframework.dll").tolist(); if(allentriesfound.any()) { foreach (fileentryinfo entry in allentriesfound) console.writeline("{0}: number: {1}", entry.path, entry.number); // here exact requirement: string result = string.join(".", allentriesfound[0].getnumbertree()); console.writeline(result); }
added way specify root directory prevent whole file system searched, usage:
var allentriesfound = enumeratefindfiles( "presentationframework.dll", stringcomparison.currentcultureignorecase, new directoryinfo(@"c:\windows")) .tolist();
Comments
Post a Comment