How to manipulate file paths intelligently in .Net 3.5?
- by Hamish Grubijan
Scenario: I am maintaining a function which helps with an install - copies files from PathPart1/pending_install/PathPart2/fileName to PathPart1/PathPart2/fileName. It seems that String.Replace() and Path.Combine() do not play well together. The code is below. I added this section:
// The behavior of Path.Combine is weird. See:
// http://stackoverflow.com/questions/53102/why-does-path-combine-not-properly-concatenate-filenames-that-start-with-path-dir
while (strDestFile.StartsWith(@"\"))
{
strDestFile = strDestFile.Substring(1); // Remove any leading backslashes
}
Debug.Assert(!Path.IsPathRooted(strDestFile), "This will make the Path.Combine(,) fail).");
in order to take care of a bug (code is sensitive to a constant @"pending_install\" vs @"pending_install" which I did not like and changed (long story, but there was a good opportunity for constant reuse). Now the whole function:
//You want to uncompress only the files downloaded. Not every file in the dest directory.
private void UncompressFiles()
{
string strSrcDir = _application.Client.TempDir;
ArrayList arrFiles = new ArrayList();
GetAllCompressedFiles(ref arrFiles, strSrcDir);
IEnumerator enumer = arrFiles.GetEnumerator();
while (enumer.MoveNext())
{
string strDestFile = enumer.Current.ToString().Replace(_application.Client.TempDir, String.Empty);
// The behavior of Path.Combine is weird. See:
// http://stackoverflow.com/questions/53102/why-does-path-combine-not-properly-concatenate-filenames-that-start-with-path-dir
while (strDestFile.StartsWith(@"\""))
{
strDestFile = strDestFile.Substring(1); // Remove any leading backslashes
}
Debug.Assert(!Path.IsPathRooted(strDestFile), "This will make the Path.Combine(,) fail).");
strDestFile = Path.Combine(_application.Client.BaseDir, strDestFile);
strDestFile = strDestFile.Replace(Path.GetExtension(strDestFile), String.Empty);
ZSharpLib.ZipExtractor.ExtractZip(enumer.Current.ToString(), strDestFile);
FileUtility.DeleteFile(enumer.Current.ToString());
}
}
Please do not laugh at the use of ArrayList and the way it is being iterated - it was pioneered by a C++ coder during a .Net 1.1 era. I will change it. What I am interested in: what is a better way of replacing PathPart1/pending_install/PathPart2/fileName with PathPart1/PathPart2/fileName within the current code. Note that _application.Client.TempDir is just _application.Client.BaseDir + @"\pending_install". While there are many ways to improve the code, I am mainly concerned with the part which has to do with String.Replace(...) and Path.Combine(,). I do not want to make changes outside of this function. I wish Path.Combine(,) took an optional bool flag, but it does not.
So ... given my constraints, how can I rework this so that it starts to suck less?