Wednesday, 7 December 2016

46 C# File and directory

File and directory information

The File and the Directory classes, which we have used in the previous couple of chapters, are great for direct file and directory manipulation. However, sometimes we wish to get information on them instead, and once again, the System.IO namespace comes to our rescue: The FileInfo and DirectoryInfo classes. In this chapter, we will look into some of the ways to use these two classes. 

First, let's explore a simple way to use the FileInfo class.
static void Main(string[] args)
{
    FileInfo fi = new FileInfo(System.Reflection.Assembly.GetExecutingAssembly().Location);
    if(fi != null)
        Console.WriteLine(String.Format("Information about file: {0}, {1} bytes, last modified on {2} - Full path: {3}", fi.Name, fi.Length, fi.LastWriteTime, fi.FullName));
    Console.ReadKey();
}
We create a new instance of the FileInfo class. It takes one parameter, which is the path to the file we want information about. We could have just specified a filename, but for fun, I thought it would be cool to get information about the actual application we are working on, that is, the EXE file that our project is compiled into. Since we don't have access to the Application project in a Console application (it's part of the WinForms assembly), we use a bit of Reflection to get the path to the current assembly. This is all way out of the scope of this particular chapter, but at least now you know. 

Once we have a FileInfo instance, we output all sorts of information about it. Try running the application and you will see. All very nice and easy, and if you look at the FileInfo class, you will see that it offers even more information, as well as shortcuts to the methods found on the File class - and why not? We have a reference to the file anyway with the FileInfo instance, so we might as well get the same options as on the File class. 

Now, information about a single file is just fine, but using the DirectoryInfo class, we can get information about all files and directories within a directory, which is obviously a very common scenario. Let me show you with a simple example:
DirectoryInfo di = new DirectoryInfo(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location));
if(di != null)
{
    FileInfo[] subFiles = di.GetFiles();
    if(subFiles.Length > 0)
    {
        Console.WriteLine("Files:");
        foreach(FileInfo subFile in subFiles)
        {
            Console.WriteLine("   " + subFile.Name + " (" + subFile.Length + " bytes)");
        }
    }
    Console.ReadKey();
}
Instead of a FileInfo instance, we create a DirectoryInfo instance. We use the same trick to get the path of the executing file, and then the GetDirectoryName() method from the Path class, to get the directory part of the path only. We use the GetFiles() method to get an array of FileInfo instances, each representing a file in the directory. We then loop through it, printing out each filename and size. 

Perhaps we want the directories as well. It's just as easy:
DirectoryInfo[] subDirs = di.GetDirectories();
if(subDirs.Length > 0)
{
    Console.WriteLine("Directories:");
    foreach(DirectoryInfo subDir in subDirs)
    {
        Console.WriteLine("   " + subDir.Name);
    }
}
In some situations, you might only want files or directories with a specific name or file extension. Fortunately, FileInfo and DirectoryInfo has some pretty good support for that as well. 

This will give us all files in the directory with a .exe extension:
FileInfo[] subFiles = di.GetFiles("*.exe");
This will give us all the directories which have the word "test" somewhere in the name:
DirectoryInfo[] subDirs = di.GetDirectories("*test*");
We can even find both files and directories recursively, which means that it will search in subdirectories of subdirectories of.... the originial directory:
FileInfo[] subFiles = di.GetFiles("*.exe", SearchOption.AllDirectories);
To only search the toplevel directory, the code would have to look like this:
FileInfo[] subFiles = di.GetFiles("*.exe", SearchOption.TopDirectoryOnly);

No comments:

Post a Comment