File Enumerator 2

From Real Software Documentation

Jump to: navigation, search

Aim
We pull the results of our last project into the file enumerator project from the previous lesson, and refine the file enumerator a bit as well. Something a bit lighter after our last project.

Contents

Analyze the Problem

Start by thinking about our objective: We want the FileEnumerator class to handle shortcuts in an intelligent way. It should do as much work as is reasonable, while leaving all the major choices up to the subclass (we did that already, for example, with the choice of whether the enumeration should be depth-first or breadth-first). So stop and think for a bit about how we should deal with shortcuts.

The first thing to notice is that the subclass should decide whether a shortcut should be followed to its original or not. The solution is to provide a FollowAlias Event that lets the subclass decide.

But here’s another, subtler design issue: should the shortcut file be enumerated as a regular file? Since we will be passing the FolderItem for the alias to the FollowAlias event, we choose to not pass that same FolderItem through to the EnumerateItem event.

This is because, if the subclass wants to process the aliases along with the other files, it can do so in the FollowAlias event quite easily. However, if instead the subclass wants to ignore the shortcuts, it doesn’t need to check each FolderItem it enumerates, to see if it is a shortcut. As for the files pointed at by the shortcuts, we enumerate them through the regular EnumerateItem event, if the FollowAlias event returns True. This design will be flexible, but simple to use, no matter what the behavior desired for aliases is.

The other issue we encounter is how to prevent shortcuts from getting us trapped in loops. This is easy to deal with now: before we enumerate a folder, we check whether its path[note 1] is in a list of the paths of already-enumerated folders. If it is in this list, we skip it; if it isn’t, we add it to the list and enumerate it and its contents.

The Project

  1. Open the file enumerator project from Lesson 18, and examine where the string accumulator could be used to avoid loops caused by shortcuts.
  2. Now open the updated version, 20_FileEnumerator2.
    The project has been rebuilt to better accommodate the new goals. The simplest way to break out encountering a shortcut into a separate event is to use a subclass. However, the code for that needs some changes in the FileEnumerator class to work properly.
    Accordingly, FileEnumerator has been modified so that rather than giving it the path to enumerate in a constructor, we pass it to the Enumerate call. This allows the subclass to recursively re-initiate the enumeration process as it needs.
    While we were making changes to this class, we also broke out encountering a folder to its own event, giving the subclass the opportunity to override enumeration of a folder. Note that the default behavior is not to enumerate the folder; the subclass must return True in the EnumerateFolder event if the folder’s contents are to be enumerated.
    Why do it this way? Because there was no good name for an event with the opposite interpretation. There is some value in having a good self-documenting name…
  3. Examine the class in which we add the alias-handling behavior.
    Notice how the events mechanism lets us “re-interpret” an event: FileEnumerator enumerates everything it encounters through the EnumerateFolder and EnumerateItem events, without regard to whether any of the items are aliases. FileAliasEnumerator intercepts that EnumerateItem event, and splits the alias enumeration off into a different event.
  4. Run the code and try it out on some medium-sized folders.
    The speed is not bad, even in the debugger.
    We probably did the speed issue to death for now, but if you have time, it might be interesting to swap in a much slower string accumulator class and see how that affects the speed.
  5. Finally, try enumerating a really big folder (say, the root of the main drive).
    If you have a lot of really deeply nested folders, you might even see a stack overflow (though it’s unlikely).
    We will consider how to resolve the stack overflow problem in a later lesson.

Further Exercises

Think about the types of utilities that could be developed based on the file enumeration capability we have here.

Before we do it in a later lesson, you might like to try to build a non-recursive version of this project.

It would be cleaner to have the FileAliasEnumerator capability folded back into the main class.

References

Notes
  1. The path of a file is a string that specifies exactly where it is. All files and folders have a unique path.
Personal tools