从目录中选择随机文件[重复]

时间:2022-05-01 00:31:52

This question already has an answer here:

这个问题在这里已有答案:

Any suggestions on how to improve this method? I am currently using it to select a single wallpaper from a directory of wallpapers

有关如何改进此方法的任何建议?我目前正在使用它从壁纸目录中选择一个壁纸

I know your not supposed to use arraylist anymore but i couldnt think of a altrnative also im not sure how to filter for more than just one type of file (ie jpg gif png) in the directory info.

我知道你不应该再使用arraylist但是我想不出一个altrnative也不知道如何在目录信息中过滤除了一种类型的文件(即jpg gif png)。

any suggestions or tweaks would be fantastic

任何建议或调整都会很棒

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();

        }

Thanks

Crash

5 个解决方案

#1


Changed to use a single instance of the pseudo-random number generator.

更改为使用伪随机数生成器的单个实例。

// 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;
}

#2


Why not use LINQ:

为什么不使用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())];

#3


As always - there is more than one way to skin a cat. I've built off of tvanfosson (correct) answer, not because this is 'more' correct; but because I think it's a useful approach.

一如既往 - 皮肤猫的方法不止一种。我已经建立了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 ""; }
}

#4


Do you really need the ArrayList at all, you should be able to eliminate it and just use the array directly once you've generated a random number.

你真的需要ArrayList,你应该能够消除它,并且只要你生成一个随机数就直接使用数组。

Also, you should check that the path is valid... if specified by a user...

此外,您应检查路径是否有效...如果用户指定...

#5


I made a few changes

我做了一些改变

here is the code i ended up using, I cut out some of the conditonals becuase they dont really matter ( if there are no files it will return null anyway no need to test twice). I also corrected for a few minor syntax errors and one user pointed out the return should be moved down.

这里是我最终使用的代码,我删除了一些条件因为它们并不重要(如果没有文件它将返回null,无论如何不需要测试两次)。我还纠正了一些小的语法错误,一个用户指出返回应该向下移动。

also in regards to the random class, Im not sure why it was bad to keep calling it but i dont see that its necessary since this will only run once every 10 to 15 min. and even then it would only create the class if files were found.

关于随机类,我不知道为什么继续调用它是不好的,但我没有看到它是必要的,因为这只会每10到15分钟运行一次。即使这样,只有找到文件才能创建类。

Thanks for everyone's help ( tvanfosson)

谢谢大家的帮助(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;
    }

#1


Changed to use a single instance of the pseudo-random number generator.

更改为使用伪随机数生成器的单个实例。

// 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;
}

#2


Why not use LINQ:

为什么不使用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())];

#3


As always - there is more than one way to skin a cat. I've built off of tvanfosson (correct) answer, not because this is 'more' correct; but because I think it's a useful approach.

一如既往 - 皮肤猫的方法不止一种。我已经建立了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 ""; }
}

#4


Do you really need the ArrayList at all, you should be able to eliminate it and just use the array directly once you've generated a random number.

你真的需要ArrayList,你应该能够消除它,并且只要你生成一个随机数就直接使用数组。

Also, you should check that the path is valid... if specified by a user...

此外,您应检查路径是否有效...如果用户指定...

#5


I made a few changes

我做了一些改变

here is the code i ended up using, I cut out some of the conditonals becuase they dont really matter ( if there are no files it will return null anyway no need to test twice). I also corrected for a few minor syntax errors and one user pointed out the return should be moved down.

这里是我最终使用的代码,我删除了一些条件因为它们并不重要(如果没有文件它将返回null,无论如何不需要测试两次)。我还纠正了一些小的语法错误,一个用户指出返回应该向下移动。

also in regards to the random class, Im not sure why it was bad to keep calling it but i dont see that its necessary since this will only run once every 10 to 15 min. and even then it would only create the class if files were found.

关于随机类,我不知道为什么继续调用它是不好的,但我没有看到它是必要的,因为这只会每10到15分钟运行一次。即使这样,只有找到文件才能创建类。

Thanks for everyone's help ( tvanfosson)

谢谢大家的帮助(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;
    }