本文转自: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. 论C# java的基本类型

    http://blog.csdn.net/com360/article/details/8201930 http://www.360doc.com/content/13/0818/13/8074294 ...

  2. python中的小技巧

    1.求1~100以内的素数 prime=filter(lambda x: not [x%i for i in range(2,x) if x%i==0], range(2,101))#列表推导,一行搞 ...

  3. JavaScript AJAX stream 流式显示

      当使用AJAX进行信息交互的时候,如果服务器返回的信息比较大,那么相对于传送完成之后的统一显示,流式显示就比较友好了. 流式实现 原理就是设置定时器,定时的查看AJAX对象的状态并更新内容,如果传 ...

  4. iOS开发之构建Widget

    原文出处: 陈凯 在 jianshu 的博客(@chenkaiHome)   欢迎分享原创到伯乐头条 伴随这iOS 8 系统多达4000项API更新而来同样还有Today Extension.而对iO ...

  5. 自己编写基于MVC的轻量级PHP框架

    做WEB开发已有三年,每次都写重复的东西, 因此,想自己写一下框架,以后开发方便.本人之前asp.NET一年开发,jsp半年,可是后来因为工作的原故换成PHP.其实很不喜欢PHP的语法.还有PHP的函 ...

  6. Notes of the scrum meeting(11/4)

    meeting time:20:00~20:30p.m.,November 4th,2013 meeting place:20号公寓楼前 attendees: 顾育豪                  ...

  7. 使用高德地图SDK获取定位信息

    使用高德地图SDK获取定位信息 第一步: 在高德官网下载SDK,如我这里需要获取定位信息,故仅下载"定位功能" 第二步: 注册成为开发者,并创建应用获取相应的key.其中,在使用A ...

  8. 安装Netsharp演示插件

    阅读本文请先阅读Netsharp下载及环境搭建 Netsharp提供了DEMO程序,DEMO完成的功能是Netsharp文章系列中的Netsharp快速入门系列中介绍的功能,DEMO是以Netshar ...

  9. Netsharp快速入门(之19) 平台常用功能(插件操作)

    作者:秋时 暗影  转载须说明出处 6.2     插件操作 6.2.1  停用/启用 1.在平台工具-插件管理,右击对应的插件可以使用启用和停用功能.插件停用后会把所有相关的页签.程序集.服务全部停 ...

  10. File "/struts-tags" not found

    前言 由于在某个jsp引用了struts标签库,导致该错误产生--这是stuts项目算是一道经典错误,往往最后的解决方式是更换Tomcat.今天我记录的是引起这一错误的一个非常隐藏的原因. 错误描述 ...