In the last blog post, you learned to read songs from an exported iTunes XML file. If you have been using iTunes for a long time and have deleted songs, merged songs from other libraries, or moved your library from one computer to another, then you may not know it, but there could be song files on your hard drive that are no longer in your iTunes library. This blog post shows you how to locate those missing files. To follow along with this blog post, read and follow the instructions in the first blog post on reading songs from iTunes.
Overview of Orphan Finding
An orphan file is a file that is located within your music folder but is not in the iTunes library. To locate these files, you need to do the following:
- Export the current iTunes library as an XML file
- Read all songs from the XML file
- Retrieve the music folder location from the XML file
- Read all files located in the music folder (and all subdirectories)
- Compare files on disk with those in the XML file
- Determine if the file is an audio/video file
- Add files missing from the XML file to a collection
- Display collection of missing files
Apple Orphan File Class
To track which files are on disk, but not in the iTunes library, create a new class to capture the path and file name. Create a property to also track whether this file is a valid audio/video file or another type of file. There might be other types of files under the music folder because iTunes put them there, or maybe you accidentally copied some other files into that folder. Add the following class to the Apple iTunes class library project.
Apple Song Orphan Finder Class
In the first blog post, you created a class named AppleSongReader to read all files in the iTunes XML file. Instead of adding functionality to this class to locate orphan files, add a new class named AppleSongOrphanFinder to the Apple iTunes class library project. Set this class to inherit from the AppleSongReader class. You can add the functionality to find orphan files to this new class. In Figure 1, you see the new AppleOrphanFinder class and the OrphanFile class that have been added to the Apple iTunes class library project.
Figure 1: Add two new classes to track orphan songs to the Apple iTunes Library DLL.
The following table describes the properties and methods in the AppleOrphanFinder class.
Structure of the AppleOrphanFinder Class
Now that you know the structure of this class, let's create the AppleOrphanFinder class. Add the properties to the AppleOrphanFinder class. Create a stub of each method as well.
Set Music Location Method
In iTunes, you can set the top-level folder where all your music files are located. Apple stores this folder name within the first <dict> element in the XML file as shown in the code below.
Write the code in the SetMusicLocation() method to read the XML library into an XElement object. Locate the first <dict> element and then read all the <key> elements within that element. Convert all <key> elements into a list and store into the _songElements property. You can now use the GetValue() method to retrieve the Music Folder key and get the value of the top-level music folder.
Is Valid Audio/Video File Method
The OrphanFile class has a property named IsAudioVideoFile. To set this property, check the file extension on each file read from the disk to see if it is contained within a set of valid audio/video file extensions. The list of valid extensions must be set prior to calling the FindOrphanFiles() method. While this method is essentially one line of code, I broke it out into a separate method in case you wish to do some other kind of file checking to determine if it is a valid file.
Find Orphan Files Method
Prior to calling the FindOrphanFiles() method make sure you call the SetMusicLocation() method and set the AudioVideoFileExtensionsproperty. The FindOrphanFiles() method reads all files from the MusicLocation property and all subdirectories under this folder. It then loops through each file found and checks if that file is in the Songs collection. If the file is not found, a new OrphanFile object is created. The IsAudioVideoFile property is set from the results of calling the IsAudioVideoFile() method. The Location property is set to the actual path and file name. This new OrphanFile object is added to the OrphanFiles property. After all files have been processed, the OrphanFiles collection is sorted in descending order on the IsAudioVideoFile property so all audio/video files are displayed first.
Modify WPF Application
You are now ready to modify the WPF application to display all orphan files. After running this process, you may see a list of orphan files as shown in Figure 2. The changes made to this window compared to the WPF window in the first blog post are as follows:
- A new row is added to accept a comma-delimited list of audio/video file extensions.
- A new button "Find Orphan Files" is added.
- A new row is added to display the folder of where the music is located.
- A new ListView control is added to display the OrphanFiles
Figure 2: Display a list of orphan files.
XAML for WPF Window
Below is the complete XAML for building the WPF window shown in Figure 2. The changes that were made are outlined in bold text.
Code Behind for WPF Window
There are a few changes you need to make in the code behind for the WPF window to read all songs and find orphan files. First, add a new field of the type AppleOrphanFinder.
Next, modify the code within the btnGetSongs_Click() event procedure to use the _Reader field variable instead of an instance of the AppSongReader. Call the SetMusicLocation() method to set the top-level folder for your music. Finally, after all songs are read, enable the "Find Orphan Files" button.
Locate Orphan Files
After reading all songs from the XML file, the "Find Orphan Files" button becomes enabled. When you click on this button, the code in the btnFindOrphans_Click() event procedure is called. This method checks if the top-level music folder exists. If it does, the AudioVideoFileExtensions property is set from the values entered in the "Audio/Video File Extensions" text box. The FindOrphanFiles() method is called and after this method runs, the lstOrphanFilesListView control is made visible and the lstSongsListView control is hidden.
Once you have the list of orphan files, you can decide if you want to delete them, or maybe re-add them back into your iTunes library.
In this blog post, you learned to locate orphan files in your iTunes music folder. To locate missing files, you need to read the top-level music folder from the Library.xml file. You then need to read all songs from the XML file and compare this list against all songs you read from the actual files located in the iTunes music folder.
You can download the complete sample code at my website. http://www.fairwaytech.com/downloads. Choose "PDSA/Fairway Blog," then "Find Orphan Song Files in iTunes" from the drop-down.