what is a good way to remove last few directory - c#

I need to parse a directory string I get and remove last few folders.
For example, when I have this directory string:
C:\workspace\AccurevTestStream\ComponentB\include
I may need to cut the last two directores to create a new directory string:
C:\workspace\AccurevTestStream
what is a good way to do this? I know I can use string split and join but I think there may be a better way to do this.

var path = "C:\workspace\AccurevTestStream\ComponentB\include";
DirectoryInfo d = new DirectoryInfo(path);
var result = d.Parent.Parent.FullName;

Here's a simple recursive method that assumes you know how many parent directories to remove from the path:
public string GetParentDirectory(string path, int parentCount) {
if(string.IsNullOrEmpty(path) || parentCount < 1)
return path;
string parent = System.IO.Path.GetDirectoryName(path);
if(--parentCount > 0)
return GetParentDirectory(parent, parentCount);
return parent;
}

You could use the System.IO.Path class in this case - if you call Path.GetDirectoryName repeatedly, it will chop off the last path:
string path = #"C:\workspace\AccurevTestStream\ComponentB\include";
path = Path.GetDirectoryName(path); //returns C:\workspace\AccurevTestStream\ComponentB
path = Path.GetDirectoryName(path); //returns C:\workspace\AccurevTestStream
//etc

You might try:
myNewString = myOriginalString.SubString(0, LastIndexOf(#"\"));
myNewString = myNewString.SubString(0, LastIndexOf(#"\"));
Not elegant, but should be effective.
Edit: (even more inelegant)
string myNewString = myOriginalString;
for(i=0;i<NumberToChop;i++)
{
if(LastIndexOf(#"\") > 0)
myNewString = myNewString.SubString(0, LastIndexOf(#"\"));
}

I'd go with the DirectoryInfo class and its Parent property.
http://msdn.microsoft.com/en-us/library/system.io.directoryinfo.aspx

static String GoUp(String path, Int32 num)
{
if (num-- > 0)
{
return GoUp(Directory.GetParent(path).ToString(), num);
}
return path;
}

The easiest way to do this:
string path = #"C:\workspace\AccurevTestStream\ComponentB\include"
string newPath = Path.GetFullPath(Path.Combine(path, #"..\..\"));
Note This goes two levels up. The result would be:
newPath = #"C:\workspace\AccurevTestStream\";

What about this (sorry, I don't know what your criteria is for determining what to delete)...
var di = new System.IO.DirectoryInfo("C:\workspace\AccurevTestStream\ComponentB\include");
while (!deleteDir)
di = di.Parent;
di.Delete(true);

Related

Remove parts of string

I have the following string
string a = #"\\server\MainDirectory\SubDirectoryA\SubdirectoryB\SubdirectoryC\Test.jpg";
I'm trying to remove part of the string so in the end I want to be left with
string a = #"\\server\MainDirectory\SubDirectoryA\SubdirectoryB";
So currently I'm doing
string b = a.Remove(a.LastIndexOf('\\'));
string c = b.Remove(b.LastIndexOf('\\'));
Console.WriteLine(c);
which gives me the correct result. I was wondering if there is a better way of doing this? because I'm having to do this in a fair few places.
Note: the SubdirectoryC length will be unknown. As it is made of the numbers/letters a user inputs
There is Path.GetDirectoryName
string a = #"\\server\MainDirectory\SubDirectoryA\SubdirectoryB\SubdirectoryC\Test.jpg";
string b = Path.GetDirectoryName(Path.GetDirectoryName(a));
As explained in MSDN it works also if you pass a directory
....passing the returned path back into the GetDirectoryName method will
result in the truncation of one folder level per subsequent call on
the result string
Of course this is safe if you have at least two directories level
Heyho,
if you just want to get rid of the last part.
You can use :
var parentDirectory = Directory.GetParent(Path.GetDirectoryName(path));
https://msdn.microsoft.com/de-de/library/system.io.directory.getparent(v=vs.110).aspx
An alternative answer using Linq:
var b = string.Join("\\", a.Split(new string[] { "\\" }, StringSplitOptions.None)
.Reverse().Skip(2).Reverse());
Some alternatives
string a = #"\\server\MainDirectory\SubDirectoryA\SubdirectoryB\SubdirectoryC\Test.jpg";
var b = Path.GetFullPath(a + #"\..\..");
var c = a.Remove(a.LastIndexOf('\\', a.LastIndexOf('\\') - 1));
but I do find this kind of string extensions generally usefull:
static string beforeLast(this string str, string delimiter)
{
int i = str.LastIndexOf(delimiter);
if (i < 0) return str;
return str.Remove(i);
}
For such repeated tasks, a good solution is often to write an extension method, e.g.
public static class Extensions
{
public static string ChopPath(this string path)
{
// chopping code here
}
}
Which you then can use anywhere you need it:
var chopped = a.ChopPath();

How combine two different Paths

I have two different Paths:
C:\Project\v4.0\Tool\Custom\CustomCompanyNames\Template\file\file.xml
C:\Destination\New\Place\Bin\Debug\output
I need a way two get values from two different paths
Expected Path:
C:\Destination\New\Place\Bin\Debug\output\CustomCompanyNames\file\file.xml
How can i solve it ?
Custom is a fix folder
All directories after Customs have different names
My Solution bad programmed:
Custom ist the first path
Destination the second path
private void test()
{
string result = destination;
string[] custom = customs.Split('\\');
foreach (var s in custom)
{
if(s.Contains("custom") || result.Contains("custom"))
{
if(s.Contains("templates")) break;
result = Path.Combine(result, s);
}
}
}
Instead of Splitting the path use IndexOf to find the Custom part and then Substring from it.
string path1 = #"C:\Project\v4.0\Tool\Custom\CustomCompanyNames\Template\file\file.xml";
string path2 = #"C:\Destination\New\Place\Bin\Debug\output";
string splitter = #"Custom\";
string desiredSection = path1.Substring(path1.IndexOf(splitter) + splitter.Length);
string output = Path.Combine(path2, desiredSection);

How to remove characters in a string?

How to remove the some characters in a string ..
string s="testpage\information.xml"
I need only information.xml how to do that?
System.IO.Path may help you with this since the string contains a file path information. In your case, you may use Path.GetFileName(string path) to get the file name from a string.
Example
string s = #"testpage\information.xml";
string filename = Path.GetFileName(s);
//MessageBox.Show(filename);
Thanks,
I hope you find this helpful :)
Assuming the value that will be in s is always a file path, use the Path class to extract the file name
var filename = Path.GetFileName(s);
File path is of the form
aaaa\bbb\ccc\dddd\information.xml
To retrieve the last string, you can divide your string using the delimiter \
String path = #"aaaa\bbb\ccc\dddd\information.xml";
String a[] = path.Split('\\');
This will give String array as ["aaaa", "bbb", "ccc", "dddd", "information.xml"]
You can retrieve the filename as
String filename = a[a.Length-1];
If it is going to be a file path, then you can use the System.IO.Path class (MSDN) to extract the filename.
string s = "testpage\information.xml"
var filename = Path.GetFilename(s);
If it's always right of the backslash separator then you can use:
if (s.Contains(#"\"))
s= s.Substring(s.IndexOf(#"\") + 1);
Hope this is what you want:
var result=s.Substring(s.LastIndexOf(#"\") + 1);
If you are using file paths, see the Path.GetFileName Method
It will not check whether the file exists or not. So it will be faster.
s = Path.GetFileName(s);
If you need to check whether file exists, use File.Exists class.
Another way is to use String.Split() method
string[] arr = s.Split('\\');
if(arr.Length > 0)
{
s = arr[arr.Length - 1];
}
Another way is to use RegEx
s = Regex.Match(s, #"[^\\]*$").Value;
You can use the following line of codes to get file extension.
string filePath = #"D:\Test\information.xml";
string extention = Path.GetExtension(filePath);
If you need file name alone use,
string filePath = #"D:\Test\information.xml";
string filename = Path.GetFilename(filePath );
Use string.Replcae
string s = #"testpage\information.xml";
s = s.Replace(#"testpage\\",""); // replace 'testpage\' with empty string
You will get Output => s=information.xml
# is need only because you have backslash in your string
For further reading about STRING REPLACE
http://www.dotnetperls.com/replace
http://msdn.microsoft.com/en-us/library/system.string.replace.aspx
In C++ you can do something like this. Basically search for "/" or "\" from right to left of the path and crop the string starting from the first occurance of the delimiter:
string ExtractFileName(const string& strPathFileName)
{
size_t npos;
string strOutput = strPathFileName;
if(strPathFileName.rfind(L'/', npos) || strPathFileName.rfind(L'\\', npos))
{
strOutput = strPathFileName.substr(npos+1);
}
return strOutput;
}

Matching subdirectory by comparing part of the directory path

I probably didn't word the title too well but hopefully my explanation should illustrate the problem.
Basically, I have to find out the names of the subdirectories excluding the file name when given another path to compare with. For instance,
Given: "C:\Windows\System32\catroot\sys.dll"
Compare: "C:\Windows"
Matched String: "\System32\catroot"
Here's another example:
Given: "C:\Windows\System32\WindowsPowerShell\v1.0\Examples\profile.ps1"
Compare: "C:\Windows\System32"
Matched String: "\WindowsPowerShell\v1.0\Examples"
What would be the best way to perform this matching?
You might also want to consider special cases such as:
Relative paths
Paths with short names such as C:\PROGRA~1 for C:\Program Files
Non-canonical paths (C:\Windows\System32\..\..\file.dat)
Paths that use an alternate separator (/ instead of \)
One way is to convert to a canonical full path using Path.GetFullPath before comparing
E.g.
string toMatch = #"C:\PROGRA~1/";
string path1 = #"C:/Program Files\Common Files\..\file.dat";
string path2 = #"C:\Program Files\Common Files\..\..\file.dat";
string toMatchFullPath = Path.GetFullPath(toMatch);
string fullPath1 = Path.GetFullPath(path1);
string fullPath2 = Path.GetFullPath(path2);
// fullPath1 = C:\Program Files\file.dat
// toMatchFullPath = C:\Program Files\
if (fullPath1.StartsWith(toMatchFullPath, StringComparison.OrdinalIgnoreCase))
{
// path1 matches after conversion to full path
}
// fullPath2 = C:\file.dat
// toMatchFullPath = C:\Program Files\
if (fullPath2.StartsWith(toMatchFullPath, StringComparison.OrdinalIgnoreCase))
{
// path2 does not match after conversion to full path
}
There is no need to use Regex.
This could be easily done using string.StartsWith, string.Substring and Path.GetDirectoryName to remove the filename.
string fullPath = #"C:\Windows\System32\WindowsPowerShell\v1.0\Examples\profile.ps1";
string toMatch = #"C:\Windows\System32";
string result = string.Empty;
if(fullPath.StartsWith(toMatch, StringComparison.CurrentCultureIgnoreCase) == true)
{
result = Path.GetDirectoryName(fullPath.Substring(toMatch.Length));
}
Console.WriteLine(result);
EDIT: this changes take care of the observation from aiodintsov and include the idea from #Joe about non-canonical or partial path names
string fullPath = #"C:\Windows\System32\WindowsPowerShell\v1.0\Examples\profile.ps1";
string toMatch = #"C:\Win";
string result = string.Empty;
string temp = Path.GetDirectoryName(Path.GetFullPath(fullPath));
string[] p1 = temp.Split('\\');
string[] p2 = Path.GetFullPath(toMatch).Split('\\');
for(int x = 0; x < p1.Length; x++)
{
if(x >= p2.Length || p1[x] != p2[x])
result = string.Concat(result, "\\", p1[x]);
}
In this case I assume that the partial match should be considered as no match.
Also take a look at the answer from #Joe for the problem of partial or non-canonical paths

Building a directory string from component parts in C#

If i have lots of directory names either as literal strings or contained in variables, what is the easiest way of combining these to make a complete path?
I know of Path.Combine but this only takes 2 string parameters, i need a solution that can take any number number of directory parameters.
e.g:
string folder1 = "foo";
string folder2 = "bar";
CreateAPath("C:", folder1, folder2, folder1, folder1, folder2, "MyFile.txt")
Any ideas?
Does C# support unlimited args in methods?
Does C# support unlimited args in methods?
Yes, have a look at the params keyword. Will make it easy to write a function that just calls Path.Combine the appropriate number of times, like this (untested):
string CombinePaths(params string[] parts) {
string result = String.Empty;
foreach (string s in parts) {
result = Path.Combine(result, s);
}
return result;
}
LINQ to the rescue again. The Aggregate extension function can be used to accomplish what you want. Consider this example:
string[] ary = new string[] { "c:\\", "Windows", "System" };
string path = ary.Aggregate((aggregation, val) => Path.Combine(aggregation, val));
Console.WriteLine(path); //outputs c:\Windows\System
I prefer to use DirectoryInfo vs. the static methods on Directory, because I think it's better OO design. Here's a solution with DirectoryInfo + extension methods, that I think is quite nice to use:
public static DirectoryInfo Subdirectory(this DirectoryInfo self, params string[] subdirectoryName)
{
Array.ForEach(
subdirectoryName,
sn => self = new DirectoryInfo(Path.Combine(self.FullName, sn))
);
return self;
}
I don't love the fact that I'm modifying self, but for this short method, I think it's cleaner than making a new variable.
The call site makes up for it, though:
DirectoryInfo di = new DirectoryInfo("C:\\")
.Subdirectory("Windows")
.Subdirectory("System32");
DirectoryInfo di2 = new DirectoryInfo("C:\\")
.Subdirectory("Windows", "System32");
Adding a way to get a FileInfo is left as an exercise (for another SO question!).
Try this one:
public static string CreateDirectoryName(string fileName, params string[] folders)
{
if(folders == null || folders.Length <= 0)
{
return fileName;
}
string directory = string.Empty;
foreach(string folder in folders)
{
directory = System.IO.Path.Combine(directory, folder);
}
directory = System.IO.Path.Combine(directory, fileName);
return directory;
}
The params makes it so that you can append an infinite amount of strings.
Path.Combine does is to make sure that the inputted strings does not begin with or ends with slashes and checks for any invalid characters.

Categories

Resources