本文转自:http://blog.ciznx.com/post/csharprandomnumberandrandomfilename.aspx

在项目中会遇到需要批量生成文件的时候,比如 asp.net 中生成静态文件、在 Winform 项目中命名临时文件等,这时我们考虑使用随机名称,也就不可避免地需要使用到 .Net 提供的 System.Random 类。对实际上,计算机不 可能产生完全随机的数字,所谓的随机数发生器都是通过一定的算法对事先选定的随机种子做复杂的运算,用产生的结果来近似的模拟完全随机数,这种随机数被称 作伪随机数。Random 类自身在 Intellisense 中也表述为“伪随机数”。伪随机数是以相同的概率从一组有限的数字中选取的。所选数字并不具有完全的随机性,但是从实用的角度而言,其随机程度已足够了。

伪随机数的选择是从随机种子开始的,所以为了保证每次得到的伪随机数都足够地“随机”,随机种子的选择就显得非常重要。如果随机种子一样,那么同一个随机数发生器产生 的随机数也会一样。一般地,我们使用同系统时间有关的参数作为随机种子,如果不给 Random 的构造函数传递参数,那 Random 会以当前系统时间由特定算法算得一个种子,这是.net Framework中的随机数发生器默认采用的方法。 也就是说,如果时间相同(纵使时间永远不会相同,但在CPU高速运行的状态下,系统获取到的时间是有可能相同的。),即使使用不同的 Random 实例,由于初始化它们的种子(系统时间)是相同的,所以Random 对象的这些实例产生的随机数仍然是相同的。这一点在实验中得到证实,实验代码如下:

using System;  

    class Program
{
static void Main(string[] args)
{
for (int i = ; i < ; i++)
{
Console.WriteLine(RandomNumber());
}
Console.WriteLine("Press any key to continue...");
Console.ReadLine();
} static int RandomNumber()
{
Random rand = new Random();
return rand.Next();
} }
在控制台输出的结果中,我们可以看到,接连输出的结果会相同,然后再变化,然后继续相同,再变化……即不规律地间歇性地变化。这个问题在 asp.net 程序中尤其明显,因为 asp.net 程序天然是多线程的,经常会遇到高并发,所以如果一个生成文件的操作由很高的并发一起执行,就可能由于生成的文件名相同而造成 IO 错误,或者相互覆盖。所以生成不重复的随机数(即“随机”的随机数)一直是一个受关注的技术话题。
其实 .Net  本身也已经提供了一些类来提供这样的支持,比如 System.Security.Cryptography.RNGCryptoServiceProvider 及 CryptGenRandom() 等

对于随机数的重复部分,有几种方法可以方便地解决。比如上述代码,可以简单地将 rand 对象的声明放在类里,作为类的静态字段来对待,然后在 RandomNumber 方法里调用它,也就是把上述代码中的 RandomNumber 代码改为:

static Random rand = new Random();
static int RandomNumber()
{
return rand.Next();
}

这样就可以解决问题了,这样一样,每次输出的随机数都会不相同:因为 rand 对象只用种子初始化了一次。

在平常的开发中,很多人习惯于将一些零散的方法都集中起来放在一个静态类中(如 Utils),我们希望诸如此类的方法在一个方法中就搞定,而上述方法中将字段 rand 的声明放到了方法的外面,这样破坏了代码的整洁性,在代码重用的时候也容易遗漏,所以还是要考虑把实现这功能的代码放在同一个方法中,这还是要面对这个问题:“如果在相同的时间获得不同的随机种子”。我们知道 Guid 类型的实例是全局不重复的值类型对象,因此使用它可以方便的作为独立的种子,即每次调用方法都使用一个从 Guid 的二进制值转换得到的数字作为种子。示例代码如下:

如果觉得这个办法的效率可能是个问题的话,也可以受此启发,而使用其他类型的实例的 GetHashCode() 的返回值作为种子。
此外,在 System.Security.Cryptography 命名空间中提供了 RNGCryptoServiceProvider类用于提供随机支持,可以用它来作为随机器的初始化种子可以用于生成随机的随机数(具体的例子,请参照 MSDN 的示例代码)

对于上述几种方法,读者您可以自行试验其效率并做对比。

好了,第一个问题解决了,那文件名呢?其实解决了第一个问题,那问题也就解决了一大半了,因为只要在同一时间产生不同的随机数,那即使是多线程也不怕了;不过还有一个问题,文件系统不允许同名的文件,因此除了要保证本次生成的文件名要不相同,还要保证与之前已经存在的文件名不相同。这也不是什么难题,使用 System.IO.File.Exist() 方法即可验证是否已存在相同的文件名,使用一个 while 循环来一直获取随机文件名,直到不与已经存在的文件名相同为止。

C#产生不重复的随机数并生成随机文件名的更多相关文章

  1. js生成1-100不重复的随机数及生成10个1-100不重复的随机数

    //生成1-100不重复的随机数 var count=100; var a=new Array(); for(var i=0;i<100;i++){ a[i]=i+1; } a.sort(fun ...

  2. 生成随机文件名JS

    export default function (length) { const data = ["0", "1", "2", " ...

  3. C#生成随机验证码

    使用YZMHelper帮助类即可 using System; using System.Web; using System.Drawing; using System.Security.Cryptog ...

  4. [转载][记录]javascript生成不重复的随机数

    参考链接:javascript生成不重复的随机数 项目播放视频,是无序的,有上下两个按钮,所以需要生成1,8不重复的随机数数组,如: ,,,,,,, 然后再split一次,就是数组了. 拿来主义了

  5. 生成N个不重复的随机数(转)

    有25幅作品拿去投票,一次投票需要选16幅,单个作品一次投票只能选择一次.前面有个程序员捅了漏子,忘了把投票入库,有200个用户产生的投票序列为空.那么你会如何填补这个漏子? 当然向上级反映情况.但是 ...

  6. C#生成无重复的随机数

    大一学期末的时候做课程设计时遇到过生成无重复随机数的问题,今天自己也写出来了: static int[] Create_Value() { Random ran = new Random(); //生 ...

  7. java,url长链接生成短链接,短链接生成器,自定义字符串,对字符串md5混合KEY加密,根据短链接获得key值,不重复的随机数,不重复的随机字符串

    java,url长链接生成短链接,短链接生成器,自定义字符串,对字符串md5混合KEY加密,根据短链接获得key值,不重复的随机数,不重复的随机字符串 package com.zdz.test; im ...

  8. Jmeter生成8位不重复的随机数

    jmeter的time函数${__time(,)}  :  默认该公式精确到毫秒级别, 13位数 ${__time(/1000,)}  : 该公式精确到秒级别, 10位数 ${__time(yyyy- ...

  9. 生成count个[0-n)不重复的随机数

    代码来自:https://www.cnblogs.com/ningvsban/p/3590722.html,感觉实现的方式不错(做了一点小小修改) public static ArrayList ge ...

随机推荐

  1. Spring Dynamic Modules - DMserver

    spring dm server 官网:http://static.springsource.com/projects/dm-server/1.0.x/programmer-guide/htmlsin ...

  2. 4.FPGA芯片管脚解释

    用户I/O:不用解释了.   配置管脚: MSEL[1:0] 用于选择配置模式,比如AS.PS等. DATA0 FPGA串行数据输入,连接到配置器件的串行数据输出管脚. DCLK FPGA串行时钟输出 ...

  3. Html5最简单的游戏Demo——Canvas绘图的弹弹球

    <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <t ...

  4. 转Oracle字符集问题总结

    Oracle字符集问题总结 分类: Oracle2006-06-04 13:48 1298人阅读 评论(3) 收藏 举报 oracle数据库sqlcharacter存储insert 作者: vston ...

  5. JavaEDU614 团队第三周项目总结

    JavaEDU614 团队第三周项目总结 本周,根据项目计划完成模块的设计代码 本项目主要是完成俄罗斯方块的基本操作.用户可以自己练习和娱乐.需要满足以下几点要求. (1)界面控制游戏开始.暂停和结束 ...

  6. android开发 获取父控件的高宽

    @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(wi ...

  7. [转载]char * 和char []的区别---之第二篇

    原文地址:http://blog.sina.com.cn/s/blog_74a4593801019keb.html main() { char *p="abc123ABC";//c ...

  8. SQL Server性能优化(2)获取基本信息

    以下常用的SQL语句有利于我们分析数据库的基本信息,然后根据查询的结果进行优化. 1. 查看索引碎片     无论何时对基础数据执行插入.更新或删除操作,SQL Server 数据库引擎都会自动维护索 ...

  9. CSS样式补充代码

    CSS符号属性: list-style-type:none; /*不编号*/ list-style-type:decimal; /*阿拉伯数字*/ list-style-type:lower-roma ...

  10. 成为嵌入式程序员应知道的0x10个基本问题

    预处理器(Preprocessor)1 . 用预处理指令#define 声明一个常数,用以表明1年中有多少秒(忽略闰年问题) #define SECONDS_PER_YEAR (60 * 60 * 2 ...