Search code examples
c#listviewdirectorygetfilesfilelist

bring multi extension files and stop looping them when the list reach the end - c#


i have a simple software that loop multi Images/videos
and show them one by one using (Next)-(previous) buttons

so far i success bring only one extension in a time using :

string[] FileList = Directory.GetFiles(Dir, "*.jpg", SearchOption.AllDirectories);

and i tried stop looping when the list reach the End by using this code :

int currentPosition = 0;
if (currentPosition != ImageList.Length) currentPosition++;

excuse my mistakes cause i still Noob in c# but when I debug its says
> IndexOutOfRangeException

and after i add multi Extensions like this :

    string[] VOut_AVI = Directory.GetFiles(@Curr_DirectoryName, "*.avi", SearchOption.AllDirectories);
    string[] VOut_MP4 = Directory.GetFiles(@Curr_DirectoryName, "*.mp4", SearchOption.AllDirectories);
    string AddMP4 = VOut_MP4[VOut_MP4.Length - 1];
    //------ Adding other format to our call ------------
    Array.Resize(ref VOut_AVI, VOut_AVI.Length + 1);
    VOut_AVI[VOut_AVI.Length - 1] = AddMP4;

    // just for test ----->>
    MessageBox.Show("Video link : " + VOut_AVI[currentPosition]);

i get this error said (XamlParserException) for that one .

if you know easy way to get multi extensions without using that much of coding like i did i'll be happy to know it also my looping process as you saw not that good if you can guide me to the right way , i'm still learning those things its a bit hard for me cause i come from a completely different environment , thanks in advance


Solution

  • To get a list of filenames with different extensions use Directory.EnumerateFiles and concat these queries.

    IEnumerable<string> myFilesQuery = new string[] { };
    
    myFilesQuery = myFilesQuery.Concat( Directory.EnumerateFiles( dir, "*.avi", SearchOption.AllDirectories ) );
    myFilesQuery = myFilesQuery.Concat( Directory.EnumerateFiles( dir, "*.mp4", SearchOption.AllDirectories ) );
    myFilesQuery = myFilesQuery.Concat( Directory.EnumerateFiles( dir, "*.jpg", SearchOption.AllDirectories ) );
    
    // nothing will happen until we call
    
    IList<string> myFiles = myFilesQuery.ToList( );
    

    If you like to have a one-line-of-code for your code, write a helper like

    public static class DirectoryHelper
    {
        public static IEnumerable<string> EnumerateFiles( 
            string path, 
            SearchOption searchOption, 
            params string[] searchPatterns )
        {
            if ( searchPatterns == null )
                throw new ArgumentNullException( nameof( searchPatterns ) );
    
            IEnumerable<string> result = new string[] { };
    
            foreach ( var searchPattern in searchPatterns )
            {
                result = result.Concat( Directory.EnumerateFiles( path, searchPattern, searchOption ) );
            }
    
            return result;
        }
    }
    

    and inside our code you have only

    IList<string> myFiles 
        = DirectoryHelper
            .EnumerateFiles( 
                dir, 
                SearchOption.AllDirectories, 
                "*.avi", "*.mp4", "*.jpg" )
            .ToList();
    

    You do not have to worry about any length of an array. The list will have the number of containing elements in the Count property.

    All collections are are zero-based and the first item has index 0 and the last item has index Count-1 (collection) or Length-1 (array). You reach the end when currentPosition >= mylist.Count-1 and you can increase the index as long as currentPosition < mylist.Count-1.

    Update

    There is already an answer here on SO dealing with multiple search patterns with a parallel implementation

    https://stackoverflow.com/a/3754470/1744164