本文转自: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. iOS学习之Object-C语言简单的通讯录管理系统

    用这几天学的OC的知识,写了一个实现简单功能的通讯录管理系统,在这里分享给大家: 通讯录管理系统 *  需求: 1.定义联系人类Contact.实例变量:姓名(拼音,首字母大写).性别.电话号码.住址 ...

  2. iOS8 超简单的设置圆角按钮 ImageView等UIView

    button.layer.cornerRadius = // 这个值根据你想要的效果可以更改 button.clipsToBounds = true 这种方法不止可以设置按钮,UIView应该都可以设 ...

  3. GNU make 总结 (一)

    make的执行依赖于一个makefile文件,该文件告诉make应该如何执行编译和链接操作.make通过比较对应文件的最后修改时间来决定哪些文件需要更新.make工具主要用来进行工程编译和程序链接操作 ...

  4. [转]rpcndr.h和wtypes.h冲突Bug的解决方案

    [转]rpcndr.h和wtypes.h冲突Bug的解决方案 http://blog.csdn.net/tzwh_86/article/details/9495133 rpcndr.h和wtypes. ...

  5. DataTemplate和ControlTemplate联系与区别

    ---恢复内容开始--- 正如标题中的两个拼接的单词所说,DataTemplate就是数据显示的模板,而ControlTemplate是控件自身的模板.(个人理解,错误请指出,谢谢) 我们看这二者在两 ...

  6. 每日会议<第二天>

    昨天:看android编程教学视频 今天:看了老师给的学姐.学长软件的代码,找到他们的优缺点,取长补短 困难:创新意识少,提不出建设性意见,缺少自己的思想

  7. boostrap中lg,md,sm,xs

    boostrap中lg,md,sm,xs分别表示多少px? .col-xs- 超小屏幕 手机 (<768px).col-sm- 小屏幕 平板 (≥768px).col-md- 中等屏幕 桌面显示 ...

  8. maven ArtifactTransferException: Failure to transfer

    我在使用Myeclipse碰见这个错误,我没有用伺服,直接连接到maven中心. ArtifactTransferException: Failure to transfer org.apache.h ...

  9. BackgroundWorker

    Constants.Worker = new BackgroundWorker(); Constants.Worker.WorkerSupportsCancellation = true; Const ...

  10. [usaco2009febgold]道路翻新 最短路+dp

    这道题居然卡SPFA,难受,写了这么长时间的SPFA,都快把dij忘光了: 设d[i][j]为修j条路到i的最短距离,然后跑堆优化dij就行了: 实测中SPFA两组大数据超时严重: dij约300ms ...