I accidentally ended up with a bunch of my directories getting borked, what should be:
/myroot/mydirectory
ended up as:
/myroot/mydirecotry/mydirectory/mydirectory
Then nesting could be any where from 1 to N times - I need to find the furthest out /mydirectory and copy all of those files back to the root and kill the duped ones. How do I find the one that is furthest out?
string[] dirs;
string actualDir = #"\myroot\";
string subdir = "mydirectory";
do
{
dirs = System.IO.Directory.GetDirectories(actualDir, subdir);
actualDir += subdir + #"\";
}
while (dirs.Length > 0);
string theLongestPath = actualDir; // The path to the furthest dir
This gets all directories in actualDir that contains subdir, until it's the last one (no other subdirectories containing subdir). If you have any questions on how it works, ask in a comment. And yeah, I've tried it, it really works.
Related
I want to create a program that gets all the .pdf-filenames (ex: test.pdf -> test) and creates an folder with that name. Also the foldername should be cropped after the first "-" (ex: A539B2AA3-GG-81234278 -> A539B2AA3).
This is the code I have made yet, but I have no clue how to proceed. I'm still a beginner, trying to learn C#:
string path = #"C:\pdfs\";
string[] filenames;
int lengtharray;
filenames = Directory.GetFiles(path, "*", SearchOption.TopDirectoryOnly)
.Where(s => (Path.GetExtension(s).ToLower() == ".pdf")).ToArray();
lengtharray = filenames.Length;
If someone can help me, I would be very happy.
Sincerely,
breadhead
You can use this code.
1) Directory.GetFiles has a wildcard support, so you can use *.pdf to search for file.
2) I added some validation in the loop, in case there are PDF file that does not have -.
string path = #"C:\pdfs\";
foreach(var file in Directory.GetFiles(path, "*.pdf", SearchOption.TopDirectoryOnly))
{
var newName = Path.GetFileName(file).Split('-');
if (!newName.Any())
continue;
Directory.CreateDirectory(Path.Combine(path,newName[0]));
}
You can simplify your file query, use filenames = Directory.GetFiles(path, "*.pdf", .... and skip the Where()-part. To loop through your list, you can use a foreach (file in filenames). As mentioned you can get the new filename with file.Split("-")[0] or with a regular expression. Then create a directory with Directory.CreateDirectory and move the file in with System.IO.File.Move("oldfilename", "newfilename");. Now you have all the bricks and you only need to glue them together
This is a lot, I know; trying to dig myself out of a hole at work.
Basically, I have many files across multiple servers that I need to get a hold of. Right now I'm running in to two problems, 1) I can't figure out the best way to search through multiple UNC paths. 2) I'm having to search by a partial name, it's possible that there is more than one file that matches, but I only want to use the file created in the last three days.
Here is my code so far. I'm not looking for someone to write it, but I would appreciate any logistical pointers.
uncPath1 = "\\server\share\";
string partial = "2002265467";
DateTime date = Convert.ToDateTime("10/5/2015");
DirectoryInfo a = new DirectoryInfo(uncPath1);
FileInfo[] interactionlist = a.GetFiles("*" + partial + "*.*", SearchOption.AllDirectories);
foreach (FileInfo f in interactionlist)
{
string fullname = f.FullName;
Console.WriteLine(fullname);
Console.Read();
}
You mentioned that you need to find only files made in the past 3 days. Instead of using Convert.ToDateTime and hard-coding the date in, you should use DateTime.Today.AddDays( -3 ) to get the date three days before the day the program is being run.
And of course, in your finding files method, compare the dates with something like:
DateTime time = DateTime.Today.AddDays( -3 );
if ( File.GetCreationTime( filePath ) > time ) {
// Add the file
}
1) You want to make a basic function that looks for a filespec in a single folder. You already wrote that in your code above, you just need to turn it into a function with parameters UNC path and filespec. Have the function take a third parameter of List<FileInfo> to add found files to.
2) If you need to search subfolders, create a function that will search a UNC path's subfolders by calling the function you wrote in #1, then getting a list of all folders, and calling itself for each folder found (and in turn, those calls will call for sub-subfolders, etc.) This is called recursion. Have this function take a List and add all found files to the List, by passing it to your #1 function.
3) Get the root UNC paths you want to search into a List or Array and then call foreach on them passing them, the filespec, and the intially empty List to the #2 function.
So:
bool FindFiles(string uncPath, string fileSpec, List<FileInfo> found);
bool FildFilesSubfolders(string uncPath, string fileSpec, List<FileInfo> found);
string fileSpec = "whatever";
string[] uncPaths = { "abc", "def" }; // etc
List<FileInfo> found = new List<FileInfo>();
foreach (string nextPath in uncPaths)
{
if (FindFilesSubfolders(nextPath, fileSpec, found))
break;
}
foreach (FileInfo f in found)
{
string fullname = f.FullName;
Console.WriteLine(fullname);
Console.Read();
}
One final thought: if you are searching subdirs and you are worried about two UNC paths that are essentially duplicates (e.g., c:\foo and c:\foo\foo2), you can use This method to check for paths within another path.
Edit: If you find something you are looking for and want to exit early, have the functions return a boolean meaning you found what you wanted to stop early. Then use break in your loops. I've edited the code.
I have an application that needs to return the names of subdirectories in a specific path. However, the path can include a variable, and towards the end of the path, I want it to check a certain folder.
My current code is something like
string path = "\\\\" + computerList + "\\C$\\Program Files (x86)\\blah1\\blah2\\";
string searchPattern = "*_*";
DirectoryInfo di = new DirectoryInfo(path);
DirectoryInfo[] directories =
di.GetDirectories(searchPattern, SearchOption.AllDirectories);
followed by
foreach (DirectoryInfo dir in directories)
{
versionInformation.Add(computerList+" "+dir.Parent.Parent.Parent+" "+dir.Parent + " " + dir.Name);
}
What I want it to do is take the results from the directory search - and then add \\working\\products\\ and iterate through that full list/path.
So - in short - I want the versionInformation list to end up being
Directory information up to blah2\ - I want it to find the folder after blah2 (which it does) but then I want to append the \\working\\products\\ and use that entire path for what it ends up searching for the *_* in.
EDIT I just realized that I may have been addressing this the wrong way - It appears that my current code actually works - But when it lists the directory names, for some reason, It comes out wrong...
foreach (DirectoryInfo dir in directories)
{
//DirectoryInfo threeLevelsUp = dir.Parent.Parent.Parent;
versionInformation.Add(computerList+" "+dir.Parent.Parent.Parent+" "+dir.Parent + " " + dir.Name);
//Console.WriteLine(dir.Parent + " " + dir.Name);
}
var beautifyList = string.Join(Environment.NewLine, versionInformation);
MessageBox.Show(beautifyList);
The first iteration for (using the below folders as an example) ICanBeDifferent will result in the FIRST item found being labeled as "ICanBeDifferent", but the SECOND result (for something found under ICanBeDifferent) would return FunTimes as the parent.parent.parent.
What could be causing this?!
Example Folders
C:\Program Files (x86)\LLL\Funtimes\ICanBeDifferent\Working\Products\Superman\2015_2_0_7
C:\Program Files (x86)\LLL\Funtimes\ICanBeDifferent\Working\Products\Office\2015_2_2_43
C:\Program Files (x86)\LLL\Funtimes\ThisIsWhatChanges\Working\Products\Lanyard\2015_2_0_70
To me it seems like you want the Path.Combine() method and use it like
string resultDir = Path.Combine(dir, "..\\working\\products");
if dir is a string or
string resultDir = Path.Combine(dir.FullName, "..\\working\\products");
if dir is a DirectoryInfo.
How do you get the last folder/directory out of user-input regardless of if the input is a path to a folder or a file? This is when the folder/file in question may not exist.
C:\Users\Public\Desktop\workspace\page0320.xml
C:\Users\Public\Desktop\workspace
I'm trying to get out the folder "workspace" out of both examples, even if the folder "workspace" or file "page0320.xml" doesn't exist.
EDIT: Using BrokenGlass's suggestion, I got it to work.
String path = #"C:\Users\Public\Desktop\workspace";
String path2 = #"C:\Users\Public\Desktop\workspace\";
String path3 = #"C:\Users\Public\Desktop\workspace\page0320.xml";
String fileName = path.Split(new char[] { '\\' }).Last<String>().Split(new char[] { '/' }).Last<String>();
if (fileName.Contains(".") == false)
{
path += #"\";
}
path = Path.GetDirectoryName(path);
You can substitute any of the path variables and the output will be:
C:\Users\Public\Desktop\workspace
Of course, this is working under the assuption that files have extensions. Fortunately, that assumption works for my purposes.
Thanks all. Been a long-time lurker and first-time poster. It was really impressive how fast and helpful the responses were :D
use Path.GetDirectoryName :
string path = Path.GetDirectoryName(#"C:\Users\Public\Desktop\workspace\page0320.xml");
string path2 = Path.GetDirectoryName(#"C:\Users\Public\Desktop\workspace\");
Note the trailing backslash in the path though in the second example - otherwise workspace will be interpreted as file name.
I will use DirectoryInfo in this way:
DirectoryInfo dif = new DirectoryInfo(path);
if(dif.Exist == true)
// Now we have a true directory because DirectoryInfo can't be fooled by
// existing file names.
else
// Now we have a file or directory that doesn't exist.
// But what we do with this info? The user input could be anything
// and we cannot assume that is a file or a directory.
// (page0320.xml could be also the name of a directory)
You can use GetFileName after GetDiretoryName from the Path class in the System.IO namespace.
GetDiretoryName will get the path without the filename (C:\Users\Public\Desktop\workspace).
GetFileName then returns the last part of the path as if it is a extensionless file (workspace).
Path.GetFileName(Path.GetDirectoryName(path));
EDIT: the path must have a trailing path separator to make this example work.
If you can make some assumptions then its pretty easy..
Assumption 1: All files will have an extension
Assumption 2: The containing directory will never have an extension
If Not String.IsNullOrEmpty(Path.GetExtension(thePath))
Return Path.GetDirectoryName(thePath)
Else
Return Path.GetFileName(thePath)
End If
Like said before, there's not really a feasible solution but this might also do the trick:
private string GetLastFolder(string path)
{
//split the path into pieces by the \ character
var parts = path.Split(new[] { Path.DirectorySeparatorChar, });
//if the last part has an extension (is a file) return the one before the last
if(Path.HasExtension(path))
return parts[parts.Length - 2];
//if the path has a trailing \ return the one before the last
if(parts.Last() == "")
return parts[parts.Length - 2];
//if none of the above apply, return the last element
return parts.Last();
}
This might not be the cleanest solution but it will work. Hope this helps!
If I have a string variable that has:
"C:\temp\temp2\foo\bar.txt"
and I want to get
"foo"
what is the best way to do this?
Use:
new FileInfo(#"C:\temp\temp2\foo\bar.txt").Directory.Name
Far be it for me to disagree with the Skeet, but I've always used
Path.GetFileNameWithoutExtension(#"C:\temp\temp2\foo\bar.txt")
I suspect that FileInfo actually touches the file system to get it's info, where as I'd expect that GetFileNameWithoutExtension is only string operations - so performance of one over the other might be better.
I think most simple solution is
DirectoryInfo dinfo = new DirectoryInfo(path);
string folderName= dinfo.Parent.Name;
Building on Handleman's suggestion, you can do:
Path.GetFileName(Path.GetDirectoryName(path))
This doesn't touch the filesystem (unlike FileInfo), and will do what's required. This will work with folders because, as the MSDN says:
Return value: The characters after the last directory character in path. If the last
character of path is a directory or volume separator character, this
method returns String.Empty. If path is null, this method returns
null.
Also, looking at the reference source confirms that GetFilename doesn't care if the path passed in is a file or a folder: it's just doing pure string manipulation.
I had an occasion when I was looping through parent child directories
string[] years = Directory.GetDirectories(ROOT);
foreach (var year in years)
{
DirectoryInfo info = new DirectoryInfo(year);
Console.WriteLine(info.Name);
Console.WriteLine(year);
//Month directories
string[] months = Directory.GetDirectories(year);
foreach (var month in months)
{
Console.WriteLine(month);
//Day directories
string[] days = Directory.GetDirectories(month);
foreach (var day in days)
{
//checkes the files in the days
Console.WriteLine(day);
string[] files = Directory.GetFiles(day);
foreach (var file in files)
{
Console.WriteLine(file);
}
}
}
}
using this line I was able to get only the current directory name
DirectoryInfo info = new DirectoryInfo(year);
Console.WriteLine(info.Name);
It'll depend on how you want to handle the data, but another option is to use String.Split.
string myStr = #"C:\foo\bar.txt";
string[] paths = myStr.Split('\\');
string dir = paths[paths.Length - 2]; //returns "foo"
This doesn't check for an array out of bounds exception, but you get the idea.