Quelle est la syntaxe pour définir plusieurs extensions de fichier comme searchPattern
sur Directory.GetFiles()
? Par exemple, filtrer les fichiers avec les extensions .aspx et .ascx.
// TODO: Set the string 'searchPattern' to only get files with
// the extension '.aspx' and '.ascx'.
var filteredFiles = Directory.GetFiles(path, searchPattern);
Update : LINQ n'est pas une option , il doit s'agir d'une searchPattern
passée dans GetFiles
, comme spécifié dans la question.
Je crois qu'il n'y a pas de solution "prête à l'emploi", c'est une limitation de la méthode Directory.GetFiles.
Il est assez facile d'écrire votre propre méthode cependant, voici un exemple .
Le code pourrait être:
/// <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)); }
var filteredFiles = Directory
.GetFiles(path, "*.*")
.Where(file => file.ToLower().EndsWith("aspx") || file.ToLower().EndsWith("ascx"))
.ToList();
Edit 2014-07-23
Vous pouvez le faire dans .NET 4.5 pour une énumération plus rapide:
var filteredFiles = Directory
.EnumerateFiles(path) //<--- .NET 4.5
.Where(file => file.ToLower().EndsWith("aspx") || file.ToLower().EndsWith("ascx"))
.ToList();
GetFiles ne peut correspondre qu’à un seul modèle, mais vous pouvez utiliser Linq pour appeler GetFiles avec plusieurs modèles:
FileInfo[] fi = new string[]{"*.txt","*.doc"}
.SelectMany(i => di.GetFiles(i, SearchOption.AllDirectories))
.ToArray();
Voir la section des commentaires ici: http://www.codeproject.com/KB/aspnet/NET_DirectoryInfo.aspx
J'aime cette méthode, car elle est lisible et évite les itérations multiples du répertoire:
var allowedExtensions = new [] {".doc", ".docx", ".pdf", ".ppt", ".pptx", ".xls", ".xslx"};
var files = Directory
.GetFiles(folder)
.Where(file => allowedExtensions.Any(file.ToLower().EndsWith))
.ToList();
var filteredFiles = Directory
.EnumerateFiles(path, "*.*") // .NET4 better than `GetFiles`
.Where(
// ignorecase faster than tolower...
file => file.ToLower().EndsWith("aspx")
|| file.EndsWith("ascx", StringComparison.OrdinalIgnoreCase))
.ToList();
Directory.EnumerateFiles
pour une amélioration des performances ( Quelle est la différence entre Directory.EnumerateFiles et Directory.GetFiles? )Ou bien, il peut être plus rapide de scinder et de fusionner vos globs (au moins, ça a l'air plus propre):
"*.ext1;*.ext2".Split(';')
.SelectMany(g => Directory.EnumerateFiles(path, g))
.ToList();
Je crains que vous deviez faire quelque chose comme ça, j'ai muté le regex de ici .
var searchPattern = new Regex(
@"$(?<=\.(aspx|ascx))",
RegexOptions.IgnoreCase);
var files = Directory.EnumerateFiles(path)
.Where(f => searchPattern.IsMatch(f))
.ToList();
Je voudrais utiliser les éléments suivants:
var ext = new string[] { ".ASPX", ".ASCX" };
FileInfo[] collection = (from fi in new DirectoryInfo(path).GetFiles()
where ext.Contains(fi.Extension.ToUpper())
select fi)
.ToArray();
EDIT: correction due à l'absence de correspondance entre Directory et DirectoryInfo
Un moyen plus efficace d’obtenir des fichiers avec les extensions ".aspx" et ".ascx" Qui évite d’interroger le système de fichiers plusieurs fois et évite le retour de nombreux fichiers non désirés rechercher et affiner le résultat par la suite:
var filteredFiles = Directory.GetFiles(path, "*.as?x")
.Select(f => f.ToLowerInvariant())
.Where(f => f.EndsWith("px") || f.EndsWith("cx"))
.ToList();
La solution facile à retenir, paresseuse et peut-être imparfaite:
Directory.GetFiles(dir, "*.dll").Union(Directory.GetFiles(dir, "*.exe"))
Au lieu de la fonction EndsWith, je choisirais d'utiliser la méthode Path.GetExtension()
à la place. Voici l'exemple complet:
var filteredFiles = Directory.EnumerateFiles( path )
.Where(
file => Path.GetExtension(file).Equals( ".aspx", StringComparison.OrdinalIgnoreCase ) ||
Path.GetExtension(file).Equals( ".ascx", StringComparison.OrdinalIgnoreCase ) );
ou:
var filteredFiles = Directory.EnumerateFiles(path)
.Where(
file => string.Equals( Path.GetExtension(file), ".aspx", StringComparison.OrdinalIgnoreCase ) ||
string.Equals( Path.GetExtension(file), ".ascx", StringComparison.OrdinalIgnoreCase ) );
(Utilisez StringComparison.OrdinalIgnoreCase
si vous vous souciez des performances: Comparaisons de chaînes MSDN )
public static bool CheckFiles(string pathA, string pathB)
{
string[] extantionFormat = new string[] { ".war", ".pkg" };
return CheckFiles(pathA, pathB, extantionFormat);
}
public static bool CheckFiles(string pathA, string pathB, string[] extantionFormat)
{
System.IO.DirectoryInfo dir1 = new System.IO.DirectoryInfo(pathA);
System.IO.DirectoryInfo dir2 = new System.IO.DirectoryInfo(pathB);
// Take a snapshot of the file system. list1/2 will contain only WAR or PKG
// files
// fileInfosA will contain all of files under path directories
FileInfo[] fileInfosA = dir1.GetFiles("*.*",
System.IO.SearchOption.AllDirectories);
// list will contain all of files that have ..extantion[]
// Run on all extantion in extantion array and compare them by lower case to
// the file item extantion ...
List<System.IO.FileInfo> list1 = (from extItem in extantionFormat
from fileItem in fileInfosA
where extItem.ToLower().Equals
(fileItem.Extension.ToLower())
select fileItem).ToList();
// Take a snapshot of the file system. list1/2 will contain only WAR or
// PKG files
// fileInfosA will contain all of files under path directories
FileInfo[] fileInfosB = dir2.GetFiles("*.*",
System.IO.SearchOption.AllDirectories);
// list will contain all of files that have ..extantion[]
// Run on all extantion in extantion array and compare them by lower case to
// the file item extantion ...
List<System.IO.FileInfo> list2 = (from extItem in extantionFormat
from fileItem in fileInfosB
where extItem.ToLower().Equals
(fileItem.Extension.ToLower())
select fileItem).ToList();
FileCompare myFileCompare = new FileCompare();
// This query determines whether the two folders contain
// identical file lists, based on the custom file comparer
// that is defined in the FileCompare class.
return list1.SequenceEqual(list2, myFileCompare);
}
Je voudrais essayer de spécifier quelque chose comme
var searchPattern = "as?x";
ça devrait marcher.
/// <summary>
/// Returns the names of files in a specified directories that match the specified patterns using LINQ
/// </summary>
/// <param name="srcDirs">The directories to seach</param>
/// <param name="searchPatterns">the list of search patterns</param>
/// <param name="searchOption"></param>
/// <returns>The list of files that match the specified pattern</returns>
public static string[] GetFilesUsingLINQ(string[] srcDirs,
string[] searchPatterns,
SearchOption searchOption = SearchOption.AllDirectories)
{
var r = from dir in srcDirs
from searchPattern in searchPatterns
from f in Directory.GetFiles(dir, searchPattern, searchOption)
select f;
return r.ToArray();
}
ressembler à cette démo:
void Main()
{
foreach(var f in GetFilesToProcess("c:\\", new[] {".xml", ".txt"}))
Debug.WriteLine(f);
}
private static IEnumerable<string> GetFilesToProcess(string path, IEnumerable<string> extensions)
{
return Directory.GetFiles(path, "*.*")
.Where(f => extensions.Contains(Path.GetExtension(f).ToLower()));
}
version c # de la réponse de @ qfactor77. C'est la meilleure façon sans LINQ.
string[] wildcards= {"*.mp4", "*.jpg"};
ReadOnlyCollection<string> filePathCollection = FileSystem.GetFiles(dirPath, Microsoft.VisualBasic.FileIO.SearchOption.SearchAllSubDirectories, wildcards);
string[] filePath=new string[filePathCollection.Count];
filePathCollection.CopyTo(filePath,0);
retourne maintenant filePath
string array. Au début vous avez besoin
using Microsoft.VisualBasic.FileIO;
using System.Collections.ObjectModel;
de plus, vous devez ajouter une référence à Microsoft.VisualBasic
J'ai fait un moyen simple pour rechercher autant d'extensions que nécessaire, sans ToLower (), RegEx, foreach ...
List<String> myExtensions = new List<String>() { ".aspx", ".ascx", ".cs" }; // You can add as many extensions as you want.
DirectoryInfo myFolder = new DirectoryInfo(@"C:\FolderFoo");
SearchOption option = SearchOption.TopDirectoryOnly; // Use SearchOption.AllDirectories for seach in all subfolders.
List<FileInfo> myFiles = myFolder.EnumerateFiles("*.*", option)
.Where(file => myExtensions
.Any(e => String.Compare(file.Extension, e, CultureInfo.CurrentCulture, CompareOptions.IgnoreCase) == 0))
.ToList();
Travailler sur .Net Standard 2.0.
var filtered = Directory.GetFiles(path)
.Where(file => file.EndsWith("aspx", StringComparison.InvariantCultureIgnoreCase) || file.EndsWith("ascx", StringComparison.InvariantCultureIgnoreCase))
.ToList();
@ Daniel B, merci de m'avoir suggéré d'écrire ma propre version de cette fonction. Il a le même comportement que Directory.GetFiles, mais supporte le filtrage regex.
string[] FindFiles(FolderBrowserDialog dialog, string pattern)
{
Regex regex = new Regex(pattern);
List<string> files = new List<string>();
var files=Directory.GetFiles(dialog.SelectedPath);
for(int i = 0; i < files.Count(); i++)
{
bool found = regex.IsMatch(files[i]);
if(found)
{
files.Add(files[i]);
}
}
return files.ToArray();
}
Je l'ai trouvé utile, alors j'ai pensé partager.