Directory.Getfiles of Certain Extension

Directory.GetFiles of certain extension

If you would like to do your filtering in LINQ, you can do it like this:

var ext = new List<string> { "jpg", "gif", "png" };
var myFiles = Directory
.EnumerateFiles(dir, "*.*", SearchOption.AllDirectories)
.Where(s => ext.Contains(Path.GetExtension(s).TrimStart(".").ToLowerInvariant()));

Now ext contains a list of allowed extensions; you can add or remove items from it as necessary for flexible filtering.

Get files of certain extension c#

Try this:

var exeFiles = Directory.EnumerateFiles(sourceDirectory, 
"*", SearchOption.AllDirectories)
.Where(s => s.EndsWith(".exe") && s.Count( c => c == '.') == 2)
.ToList();

How can i get all files on disk with a specific extension using 'Directory.getFiles' and save them in a list

There are two things you can do to improve that code:

  1. Use Directory.EnumerateFiles() and Directory.EnumerateDirectories() to avoid making a copy of the names of all the files in each directory.
  2. Make the return type of the method IEnumerable<string> to make it easier to consume.

We also need to be very careful about exceptions caused by attempting to access protected files and directories. The code below is also complicated by the fact that you're not allowed to yield return from inside a try/catch block, so we have to rearrange the code somewhat.

(Also note that we have to dispose the enumerator returned from .GetEnumerator(); normally this is done automatically when you use foreach, but in this case we can't - because of having to avoid doing yield return in a try/catch - so we have to use using to dispose it.)

Here's a modification of your original code to do this:

public static IEnumerable<string> GetFiles(string root, string spec)
{
var pending = new Stack<string>(new []{root});

while (pending.Count > 0)
{
var path = pending.Pop();
IEnumerator<string> fileIterator = null;

try
{
fileIterator = Directory.EnumerateFiles(path, spec).GetEnumerator();
}

catch {}

if (fileIterator != null)
{
using (fileIterator)
{
while (true)
{
try
{
if (!fileIterator.MoveNext()) // Throws if file is not accessible.
break;
}

catch { break; }

yield return fileIterator.Current;
}
}
}

IEnumerator<string> dirIterator = null;

try
{
dirIterator = Directory.EnumerateDirectories(path).GetEnumerator();
}

catch {}

if (dirIterator != null)
{
using (dirIterator)
{
while (true)
{
try
{
if (!dirIterator.MoveNext()) // Throws if directory is not accessible.
break;
}

catch { break; }

pending.Push(dirIterator.Current);
}
}
}
}
}

As an example, here's how you could use a console app to list all the accessible ".txt" files on the "C:\" drive:

static void Main()
{
foreach (var file in GetFiles("C:\\", "*.txt"))
{
Console.WriteLine(file);
}
}

Using Directory.GetFiles() to select all the files but a certain extension

You don't need a regex if you want to filter extension(s):

// for example a field or property in your class
private HashSet<string> ExtensionBlacklist { get; } =
new HashSet<string>(StringComparer.InvariantCultureIgnoreCase)
{
".html",
".htm"
};
// ...

var filteredFiles = Directory.EnumerateFiles(path, "*.*")
.Where(fn => !ExtensionBlacklist.Contains(System.IO.Path.GetExtension(fn)))
.ToList();

Find a file with a certain extension in folder

Look at the System.IO.Directory class and the static method GetFiles. It has an overload that accepts a path and a search pattern. Example:

 string[] files = System.IO.Directory.GetFiles(path, "*.txt");

How to I get all files from a directory with a variable extension of specified length?

I don't believe there's a way you can do this without looping through the files in the directory and its subfolders. The search pattern for GetFiles doesn't support regular expressions, so we can't really use something like [\d]{7} as a filter. I would suggest using Directory.EnumerateFiles and then return the files that match your criteria.

You can use this to enumerate the files:

private static IEnumerable<string> GetProprietaryFiles(string topDirectory)
{
Func<string, bool> filter = f =>
{
string extension = Path.GetExtension(f);
// is 8 characters long including the .
// all remaining characters are digits
return extension.Length == 8 && extension.Skip(1).All(char.IsDigit);
};

// EnumerateFiles allows us to step through the files without
// loading all of the filenames into memory at once.
IEnumerable<string> matchingFiles =
Directory.EnumerateFiles(topDirectory, "*", SearchOption.AllDirectories)
.Where(filter);

// Return each file as the enumerable is iterated
foreach (var file in matchingFiles)
{
yield return file;
}
}

Path.GetExtension includes the . so we check that the number of characters including the . is 8, and that all remaining characters are digits.

Usage:

List<string> fileList = GetProprietaryFiles(someDir).ToList();

Multiple file-extensions searchPattern for System.IO.Directory.GetFiles

I believe there is no "out of the box" solution, that's a limitation of the Directory.GetFiles method.

It's fairly easy to write your own method though, here is an example.

The code could be:

/// <summary>
/// Returns file names from given folder that comply to given filters
/// </summary>
/// <param name="SourceFolder">Folder with files to retrieve</param>
/// <param name="Filter">Multiple file filters separated by | character</param>
/// <param name="searchOption">File.IO.SearchOption,
/// could be AllDirectories or TopDirectoryOnly</param>
/// <returns>Array of FileInfo objects that presents collection of file names that
/// meet given filter</returns>
public string[] getFiles(string SourceFolder, string Filter,
System.IO.SearchOption searchOption)
{
// ArrayList will hold all file names
ArrayList alFiles = new ArrayList();

// Create an array of filter string
string[] MultipleFilters = Filter.Split('|');

// for each filter find mathing file names
foreach (string FileFilter in MultipleFilters)
{
// add found file names to array list
alFiles.AddRange(Directory.GetFiles(SourceFolder, FileFilter, searchOption));
}

// returns string array of relevant file names
return (string[])alFiles.ToArray(typeof(string));
}

Can you call Directory.GetFiles() with multiple filters?

For .NET 4.0 and later,

var files = Directory.EnumerateFiles("C:\\path", "*.*", SearchOption.AllDirectories)
.Where(s => s.EndsWith(".mp3") || s.EndsWith(".jpg"));

For earlier versions of .NET,

var files = Directory.GetFiles("C:\\path", "*.*", SearchOption.AllDirectories)
.Where(s => s.EndsWith(".mp3") || s.EndsWith(".jpg"));

edit: Please read the comments. The improvement that Paul Farry suggests, and the memory/performance issue that Christian.K points out are both very important.

Directory.GetFiles - Search pattern for file extensions

Is there a way to specify the end of the extension?

There isn't a way to do this directly. The best option would be to switch to Directory.EnumerateFiles and filter afterwards:

var files = Directory.EnumerateFiles(@"C:\Folder", "*.asp", SearchOption.AllDirectories)
.Where(f => f.EndsWith(".asp", StringComparison.OrdinalIgnoreCase));

This is because the Directory methods have specific behavior which prevents this from working directly. From the docs:

If the specified extension is exactly three characters long, the method returns files with extensions that begin with the specified extension. For example, "*.xls" returns both "book.xls" and "book.xlsx".

This is an exception to the normal search rules, but, in your case, is working against you. Using EnumerateFiles streams the results, and filtering afterwards allows you to find only the proper matches.

Directory.getfiles(): specific names of files c#

Use LINQ and EnumerateFiles instead of GetFiles + Path.GetFilenameWithoutExtension:

string[] extensions = { "_fv", "_body", "_out" };
string[] fileEntriesout = System.IO.Directory.EnumerateFiles(dir + "\\" + "output\\", "*.csv", System.IO.SearchOption.AllDirectories)
.Where(file => extensions.Any(ex => Path.GetFileNameWithoutExtension(file).EndsWith(ex)))
.ToArray();

String.EndsWith has an overoad that takes a StringComparison, if you want to ignore the case(f.e. allow _Body too):

EndsWith(ex, StringComparison.InvariantCultureIgnoreCase)


Related Topics



Leave a reply



Submit