简体   繁体   中英

How do I create a list of filenames from a folder in C#

I got a problem when i want to populate an array with the file names.

the code is:

 string [] arrays= {};
 String sdira= "path of the directory";

 foreach (string d in Directory.GetDirectories(sdira))
 {

   foreach (string f in Directory.GetFiles(d, "*.*"))`enter code here`
   {
     int j = 0;

     array[j++] = path.getfiles(f);
   }

 }

when i loop through array, the array contains nothing :( so how to fill the array in this case? or any better solution :)

you are resetting j to 0 at the begning of each iteration of the loop.

How about this:

List<string> files = new List<string>();
String sdira = "path of the directory";

foreach (string d in Directory.GetDirectories(sdira)) {

    foreach (string f in Directory.GetFiles(d, "*.*")) {
       files.Add(f);
    }
}

Solution as posted on your other question . This eliminates the need to loop at all

string [] arrays;
String sdira= "path of the directory";

arrays =  Directory.GetFiles(sdira, "*", SearchOption.AllDirectories).Select(x => Path.GetFileName(x)).ToArray();

could also do

arrays = Directory.GetFiles(sdira, "*", SearchOption.AllDirectories)
    .Where(s => (Path.GetExtension(s).ToLower() == extensionType)).ToArray();

if you want to only get say .jpg (seemed indicated in your other question) the extensionType = ".jpg"

You need to specify the length of the array before filling it.

string[] array = new string[16]; // this will create an arrray of length 16. 

In your case, you will need to initialize the length of the array to the amount of files in the directory.

In case you want to search the directories recursively, you will be better off using a list instead of an array.

Instead of using an array you should better use a List<string> . The array has a fixed length, but you do not know the number of files, before you query all directories.

var files = new List<string>(); 
string sdira= "path of the directory"; 
foreach (string d in Directory.GetDirectories(sdira)) {   
    files.AddRange(Directory.GetFiles(d, "*.*"));   
}

// To use
foreach(string file in files) { }
string file2 = files[2]; 
// or convert to array
string[] arrays = files.ToArray();

// Or to use as datasource    
comboBox1.DataSource = files;

Given that you don't know the size of the array you are using I think you'd be much better off using a generic collection like List<T> , ie

 List<string> Filenames = List<string>();
 String sdira= "path of the directory";

 foreach (string d in Directory.GetDirectories(sdira))
 {
   foreach (string f in Directory.GetFiles(d, "*.*"))
   {
       Filenames.Add(f);
   }
 }

Kind of a chicken and egg thing going on here, when you create your arrays object you need to specify the size of the array. However you can't do that until you have looked in the directories. Running over the directory list twice would be a bad idea.

I would suggest that you use a System.Collections.Generic.List object as an intermediary as this negates the need to specify the size of the initial string array, you can then convert that to your string array (in fact you may not need to do that at all depending on what you app is doing with your arrays object. For example:

System.Collections.Generic.List<string> filesList = new System.Collections.Generic.List<string>();
string path = @"c:\my\directory\";

foreach (string directory in System.IO.Directory.GetDirectories(path))
{
    foreach (string file in System.IO.Directory.GetFiles(directory))
    {
        filesList.Add(file);
    }
}

string[] filesArray = filesList.ToArray();

EDIT : Updated code sample with a defensive directory exists check and also retrieval of files from the base directory:

System.Collections.Generic.List<string> filesList = new System.Collections.Generic.List<string>();
string path = @"c:\my\directory\";

if (System.IO.Directory.Exists(path))
{
    //Get files for the base path
    string[] baseDirectoryFiles = System.IO.Directory.GetFiles(path);
    filesList.AddRange(baseDirectoryFiles);

    // Get files in subdirectories (first level) of base path
    foreach (string directory in System.IO.Directory.GetDirectories(path))
    {
        string[] directoryFiles = System.IO.Directory.GetFiles(directory);
        filesList.AddRange(directoryFiles);
    }

    string[] filesArray = filesList.ToArray();
}
else
{
    //Your directory was not found on the filesystem
    //handle as appropriate
}

This will get all files in the base directory and the first level of sub directories, it will not however get file names from sub directories of sub directories. To support that you should look at a recursive method.

EDIT

Here is a sample that show how to do this recursively, and therefore get all files from all directories regardless of depth:

private void MyMethod()
{
    List<string> fileNames = new List<string>();
    GetFileNames(@"C:\my\base\directory", fileNames);
}

private void GetFileNames(string directory, List<string> files)
{
    files.AddRange(System.IO.Directory.GetFiles(directory));

    foreach(string subDirectory in System.IO.Directory.GetDirectories(directory))
    {
        GetFileNames(subDirectory, files);
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM