我如何快速创build大(> 1GB)的文本+二进制文件与“自然”的内容? (C#)

为了testing压缩的目的,我需要能够创build大文件,最好是文本,二进制和混合格式。

  • 文件的内容不应该是完全随机的,也不是统一的。
    全零的二进制文件是不好的。 完全随机数据的二进制文件也不好。 对于文本来说,一个带有ASCII随机序列的文件并不好 – 文本文件应该有模仿自然语言的模式和频率,或者源代码(XML,C#等)。 伪真实文本。
  • 每个单独文件的大小并不重要,但是对于这组文件,我需要总大小为〜8GB。
  • 我想保持文件的数量在一个可pipe理的水平,让我们说o(10)。

对于创build二进制文件,我可以新build一个大的缓冲区,然后在一个循环中执行System.Random.NextBytes和FileStream.Write,如下所示:

Int64 bytesRemaining = size; byte[] buffer = new byte[sz]; using (Stream fileStream = new FileStream(Filename, FileMode.Create, FileAccess.Write)) { while (bytesRemaining > 0) { int sizeOfChunkToWrite = (bytesRemaining > buffer.Length) ? buffer.Length : (int)bytesRemaining; if (!zeroes) _rnd.NextBytes(buffer); fileStream.Write(buffer, 0, sizeOfChunkToWrite); bytesRemaining -= sizeOfChunkToWrite; } fileStream.Close(); } 

有了足够大的缓冲区,比如512k,即使对于2或3gb以上的文件,这也是相对较快的。 但内容完全是随机的,这不是我想要的。

对于文本文件,我采取的方法是使用Lorem Ipsum ,并通过StreamWriter重复发送到文本文件。 内容是非随机的,不均匀的,但它有许多相同的重复块,这是不自然的。 另外,因为Lorem Ispum块非常小(<1k),所以需要很多循环和很长的时间。

这些对我来说都不是很满意。

我见过的答案在Windows系统上快速创build大文件? 。 这些方法是非常快的,但我认为他们只是用零填充文件,或随机数据,这两者都不是我想要的。 如果需要,运行像contig或fsutil这样的外部过程,我没有问题。

testing在Windows上运行。
而不是创build新文件,只使用文件系统中已经存在的文件更有意义吗? 我不知道有多大。

那么从一个单独的现有文件(可能是c:\ windows \ Microsoft.NET \ Framework \ v2.0.50727 \ Config \ enterprisesec.config.cch文件)开始并复制其内容很多次呢? 这可以用于文本或二进制文件。

目前我有一种方法,但它需要很长时间才能运行。

有没有人解决了这个问题?

有没有比通过StreamWriter写一个文本文件更快的方法?

build议?

编辑 :我喜欢马尔可夫链的想法,以产生更自然的文本。 尽pipe如此,仍然需要面对速度问题。

Solutions Collecting From Web of "我如何快速创build大(> 1GB)的文本+二进制文件与“自然”的内容? (C#)"

我想你可能正在寻找像马尔可夫链过程来产生这些数据。 它既是随机的(随机的),也是结构化的,因为它是基于有限状态机运行的 。

事实上,马尔可夫链已被用于生成人类语言中半真实的文本。 一般来说,它们不是一件可以正确分析的小事,但它们具有某些特性的事实对于你来说应该是足够好的。 (同样,请参阅页面的马尔可夫链属性部分。)但是,希望您应该看看如何设计一个,实现它实际上是一个非常简单的概念。 你最好的办法是创建一个通用的马尔可夫过程框架,然后分析自然语言或源代码(无论你想随机数据模拟)以“训练”你的马尔可夫过程。 最后,根据您的要求,这应该会为您提供非常高质量的数据。 如果你需要这些巨大的测试数据,那么值得去努力。

对于文本,你可以使用堆栈溢出社区转储 ,那里有300megs的数据。 使用我写的应用程序只需要大约6分钟的时间就可以加载到数据库中,并且可能几乎在同一时间将所有文章转储到文本文件,根据您的方法,您可以轻松地为您提供20万到100万个文本文件(与源和XML混合在额外的奖金)。

你也可以使用像维基百科转储这样的东西,它似乎以MySQL格式发布,这将使得它非常容易使用。

如果您正在寻找一个可以拆分的大文件,那么为了实现二进制目的,您可以使用本地翻录的VM vmdk或DVD。

编辑

Mark提到gutenberg下载项目,这也是一个非常好的文本(和音频)源,可以通过bittorrent下载 。

你总是可以编写一个自己的网页爬虫…

更新冷静的家伙,这是一个很好的答案, 如果他没有说他已经有一个“花费太长时间”的解决方案。

这里的快速检查似乎表明,下载8GB的任何东西都需要相当长的时间。

我认为Windows目录可能会成为您需要的足够好的资源。 如果你是在文本之后,我会通过寻找.txt文件的每个目录递归,并通过它们循环复制它们到你的输出文件多次,以获得正确的大小的文件。

然后,您可以通过查找.exes或.dlls来使用类似于二进制文件的方法。

对于文本文件,您可能会取得英文单词列表的一些成功,并随意抽出单词。 这不会产生真正的英文文本,但我想这将产生一个字母频率类似于你可能会发现英文。

对于一个更结构化的方法,你可以使用马尔可夫链训练一些大的免费英文文本。

你为什么不把Lorem Ipsum和你的输出之前在内存中创建一个长字符串。 如果您每次增加文本数量,则文本应以O(log n)的速度扩展。 你甚至可以在手前计算数据的总长度,这样你就不必再把内容复制到新的字符串/数组中了。

由于你的缓冲区只有512K或者你设置的任何东西,所以在写入数据之前你只需要生成那么多的数据,因为这只是你一次可以写入文件的数量。 你会一遍又一遍地写同一个文本,所以只需要使用你第一次创建的原始的512k。

维基百科非常适合用于混合文本和二进制文件的压缩测试。 如果你需要基准比较, Hutter奖网站可以为维基百科的前100MB提供高水位标志。 目前的记录是一个6.26的比例,16mb。

感谢所有的快速输入。 我决定分别考虑速度和“自然”的问题。 为了生成自然文本,我结合了一些想法。

  • 为了生成文本,我从Mark Rushakoff建议的项目gutenberg目录中的几个文本文件开始。
  • 我随机选择并下载该子集的一个文档。
  • 然后,我使用Noldorin建议的马尔可夫过程,使用下载的文本作为输入。
  • 我用C#编写了一个新的马尔可夫链,使用Pike经济的Perl实现作为例子。 它一次生成一个文本一个字。
  • 为了提高效率,代码使用纯马尔可夫链来一次生成1GB的文本,代码生成一个〜1MB的随机文本,然后重复地随机抽取这些文本,并将它们聚集在一起。

更新 :至于第二个问题,速度 – 我采取了尽可能多的IO尽可能多的方法,这是我的可怜的笔记本电脑与一个5400转迷你主轴。 这导致我完全重新定义问题 – 而不是随机生成一个文件 ,我真正想要的是随机内容。 使用包裹在马尔可夫链上的流,我可以在内存中生成文本并将其流式传输到压缩器,从而消除8g的写入和8g的读取。 对于这个特定的测试,我不需要验证压缩/解压缩往返,所以我不需要保留原来的内容。 所以流式处理方式很好地加速了事情的发展。 它削减了所需时间的80%。

我还没有想出如何做二进制代码,但它可能是类似的东西。

再次感谢所有有用的想法。