In my new code I am not using strings to pass directory paths or file names. Instead I am using DirectoryInfo and FileInfo as they seem to encapsulate a lot of information.
I have seen a lot of code that uses strings to pass directory information then they "split" and "mid" and "instr" in long incomprehensible statements until they get the part of the directory they are looking for.
Is there any good reason to pass paths as strings?
In general, I think keeping the information in FileInfo/DirectoryInfo is better. There is a lot of useful functionality in these classes, as well as a lot of safety involved in that it's much easier to check for existence of a file, see the originally specified file, etc.
The only place where I would (potentially) pass a path as as a string instead of using FileInfo and DirectoryInfo would if the path was going to be passed across AppDomains or between processes, etc.
FileInfo and DirectoryInfo both work fine across AppDomain boundaries (since they're Serializable), but they have a fair amount more overhead in this situation. If things are going back and forth a lot, it could have an impact.
I would stick with FileInfo and DirectoryInfo in this case, though, unless I found that there was a noticeable problem during my profiling, and I was trying to reduce the amount of serialized data. If I didn't run into performance issues, I'd stick with using these classes, as they provide a lot of safety and functionality.
DirectoryInfo
and FileInfo
are awful heavy for passing around if all you need is a path. I'd be more concerned about the "split and mid and instr" junk. Learn the ways of:
Path.GetFileName
Path.GetDirectoryName
Path.Combine
etc...
Those are from the System.IO.Path
class, btw.
Once the path is in an application (i.e. not in a plain text configuration file), no, there isn't a good reason.
The only time (I can think of) it could be useful is when interoperating with code that only accepts paths as strings.
I think you do need a class to encapsulate a file or directory path, instead of using raw strings and manipulating them using the static System.IO.Path class. However, I don't find DirectoryInfo and FileInfo suitable, because they seem to be intended more for doing file/directory manipulations instead of path operations. If you make a custom class for path manipulation, you can provide more user friendly path manipulation functionality.
One significant difference between path string and FileInfo to bear in mind, which can be summarized in the tests below:
A FileInfo reflects the info about the file as of when it was instantiated - it can be deleted/modified and the FileInfo won't reflect that.
[TestMethod]
public void TestFileInfo()
{
var path = @"C:\Users\bjarmuz\Desktop\aybabtu.txt";
File.WriteAllText(path, "All your base are belong to us!");
var file = new FileInfo(path);
Assert.IsTrue(file.Exists);
File.Delete(file.FullName);
Assert.IsTrue(file.Exists);
Assert.IsFalse(File.Exists(file.FullName));
}
[TestMethod]
public void TestFileInfo()
{
var path = @"C:\Users\bjarmuz\Desktop\aybabtu.txt";
File.WriteAllText(path, "All your base are belong to us!");
Thread.Sleep(1000);
var file = new FileInfo(path);
var date = DateTime.UtcNow;
Assert.IsTrue(file.LastWriteTimeUtc< date);
File.WriteAllText(path, "No!");
Assert.IsTrue(File.GetLastWriteTimeUtc(file.FullName)> date);
Assert.IsFalse(file.LastWriteTimeUtc > date);
}
This can be somewhat misleading, and if your code passes around FileInfos instead of strings, you might see incorrect results for the properties such as Exists
or Last[..]Time
- which would not happen if you'd use the File.Get[...]()
methods.
However, on the other hand, you should not rely on the File.Exists() method either - because the file can be created/deleted just after you run the tests. Proper way for that is to NOT do this check, and rather accept that it can throw the IO exception (and be ready to handle it properly). More info in this great article https://blogs.msdn.microsoft.com/ericlippert/2008/09/10/vexing-exceptions/
Also, a significant 'upside' of FileInfo/DirectoryInfo is that it protects your method (and the method consumers) from this:
void SaveEntity(Entity theThing, string path)
{
//now, based on the signature, you don't know whether you need file path or directory path
}
//void SaveEntity(Entity theThing, DirectoryInfo path) {}
//void SaveEntity(Entity theThing, FileInfo path) {}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With