Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Good reasons to pass paths as strings instead of using DirectoryInfo/FileInfo

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?

like image 812
user79755 Avatar asked Mar 20 '09 18:03

user79755


5 Answers

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.

like image 82
Reed Copsey Avatar answered Nov 15 '22 19:11

Reed Copsey


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.

like image 30
Chris Avatar answered Nov 15 '22 21:11

Chris


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.

like image 6
Sean Bright Avatar answered Nov 15 '22 19:11

Sean Bright


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.

like image 1
Dimitri C. Avatar answered Nov 15 '22 19:11

Dimitri C.


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) {}
like image 1
Bartosz Avatar answered Nov 15 '22 20:11

Bartosz