Выбрать случайный файл из каталога

Любые предложения о том, как улучшить этот метод? В настоящее время я использую его, чтобы выбрать один обои из каталога обоев

Я знаю, что вы больше не должны использовать 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;
    }
Другие вопросы по тегам