Выбрать случайный файл из каталога
Любые предложения о том, как улучшить этот метод? В настоящее время я использую его, чтобы выбрать один обои из каталога обоев
Я знаю, что вы больше не должны использовать arraylist, но я не мог придумать альтернативу, также я не уверен, как отфильтровать более одного типа файла (например, jpg gif png) в информации каталога.
любые предложения или настройки были бы фантастическими
private string getrandomfile(string path)
{
ArrayList al = new ArrayList();
DirectoryInfo di = new DirectoryInfo(path);
FileInfo[] rgFiles = di.GetFiles("*.*");
foreach (FileInfo fi in rgFiles)
{
al.Add(fi.FullName);
}
Random r = new Random();
int x = r.Next(0,al.Count);
return al[x].ToString();
}
Спасибо
авария
5 ответов
Изменено использование одного экземпляра генератора псевдослучайных чисел.
// Use a class variable so that the RNG is only created once.
private Random generator;
private Random Generator
{
get
{
if (this.generator == null)
{
this.generator = new Random();
}
return this.generator;
}
}
private string getrandomfile(string path)
{
string file = null;
if (!string.IsNullOrEmpty(path))
{
var extensions = new string[] { ".png", ".jpg", ".gif" };
try
{
var di = new DirectoryInfo(path);
var rgFiles = di.GetFiles("*.*")
.Where( f => extensions.Contains( f.Extension
.ToLower() );
int fileCount = rgFiles.Count();
if (fileCount > 0)
{
int x = this.Generator.Next( 0, fileCount );
file = rgFiles.ElementAt(x).FullName;
}
}
// probably should only catch specific exceptions
// throwable by the above methods.
catch {}
}
return file;
}
Почему бы не использовать LINQ:
var files = Directory.GetFiles(path, "*.*").Where(s => Regex.Match(s, @"\.(jpg|gif|png)$").Success);
string randFile = path + files.ToList()[r.Next(0, files.Count())];
Как всегда - существует более одного способа кожи кошки. Я построил ответ на tvanfosson (правильный) не потому, что это "более" правильно; но потому что я думаю, что это полезный подход.
private static string getRandomFile(string path)
{
try
{
var extensions = new string[] { ".png", ".jpg", ".gif" };
var di = new DirectoryInfo(path);
return (di.GetFiles("*.*")
.Where(f => extensions.Contains(f.Extension
.ToLower()))
.OrderBy(f => Guid.NewGuid())
.First()).FullName ;
}
catch { return ""; }
}
Вам действительно нужен ArrayList, вы должны быть в состоянии устранить его и просто использовать массив сразу после того, как вы сгенерировали случайное число.
Кроме того, вы должны проверить, что путь действителен... если указан пользователем...
Я сделал несколько изменений
вот код, который я в итоге использовал, я вырезал некоторые условия, потому что они не имеют большого значения (если нет файлов, он все равно вернет null, нет необходимости проверять дважды). Я также исправил несколько незначительных синтаксических ошибок, и один пользователь указал, что возврат должен быть перемещен вниз.
Также, что касается случайного класса, я не уверен, почему было плохо продолжать вызывать его, но я не вижу в этом необходимости, так как он будет выполняться только раз в 10-15 минут. и даже тогда он будет создавать класс, только если будут найдены файлы.
Спасибо всем за помощь (tvanfosson)
private string getrandomfile2(string path)
{
string file = null;
if (!string.IsNullOrEmpty(path))
{
var extensions = new string[] { ".png", ".jpg", ".gif" };
try
{
var di = new DirectoryInfo(path);
var rgFiles = di.GetFiles("*.*").Where( f => extensions.Contains( f.Extension.ToLower()));
Random R = new Random();
file = rgFiles.ElementAt(R.Next(0,rgFiles.Count())).FullName;
}
// probably should only catch specific exceptions
// throwable by the above methods.
catch {}
}
return file;
}