繁体   English   中英

如何快速创建具有“自然”内容的大型(> 1gb)文本+二进制文件? (C#)

[英]How can I quickly create large (>1gb) text+binary files with “natural” content? (C#)

为了测试压缩,我需要能够创建大文件,最好是文本,二进制和混合格式。

  • 文件的内容不应完全随机,也不能统一。
    全零的二进制文件是不好的。 具有完全随机数据的二进制文件也不是很好。 对于文本,具有完全随机的ASCII序列的文件不是很好-文本文件应具有模拟自然语言或源代码(XML,C#等)的模式和频率。 伪真实文本。
  • 每个文件的大小并不重要,但是对于文件集,我需要总数为〜8gb。
  • 我想将文件数量保持在可管理的水平,比方说o(10)。

为了创建二进制文件,我可以新建一个大缓冲区并在循环中依次执行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系统上快速创建大文件的答案了吗? 这些方法非常快速,但是我认为它们只是用零或随机数据填充文件,而这都不是我想要的。 如果有必要,我可以运行诸如contig或fsutil之类的外部进程没有问题。

测试在Windows上运行。
而不是创建新文件,仅使用文件系统中已经存在的文件有意义吗? 我不知道有足够大的东西。

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

目前,我有一种可以完成此类工作的方法,但是运行时间太长。

还有其他人解决吗?

是否有比通过StreamWriter更快的方法来编写文本文件?

有什么建议吗?

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

对于文本,您可以使用堆栈溢出社区转储 ,那里有300兆数据。 使用我编写的应用程序将其加载到数据库中仅需6分钟,并且可能大约在同一时间将所有帖子转储到文本文件中,这很容易为您提供200K到100万个文本文件之间的任意位置,具体取决于您的处理方式(还有将源代码和xml混合在一起的额外好处)。

您也可以使用Wikipedia dump之类的东西,它似乎以MySQL格式提供,这使它使用起来非常容易。

如果您正在寻找可以拆分的大文件(出于二进制目的),则可以在本地使用VM vmdk或DVD。

编辑

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

您总是可以给自己编写一个小的网络爬虫...

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

在此处进行快速检查似乎表明下载8GB的内容将花费相对较长的时间。

我认为您可能正在寻找类似马尔可夫链的过程来生成此数据。 它既是随机的(随机的),又是结构化的,因为它基于有限状态机运行

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

我认为Windows目录可能会满足您的需求。 如果您想输入文本,我将遍历每个目录以查找.txt文件,并循环遍历它们,以根据需要将它们复制到您的输出文件中多次,以获得合适的文件大小。

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

对于文本文件,采用英文单词列表并从中随机抽取单词可能会有些成功。 这不会产生真实的英语文本,但我想它将产生与您在英语中发现的字母频率相似的字母频率。

对于更结构化的方法,您可以使用在一些大型免费英语文本上训练的马尔可夫链

您为什么不只接受Lorem Ipsum并在输出之前在内存中创建一个长字符串。 如果您每次都将文本量加倍,则文本应以O(log n)的速率扩展。 您甚至可以事先计算数据的总长度,从而不必将内容复制到新的字符串/数组中。

由于缓冲区只有512k或设置为512k的任何值,因此您只需要在写入之前生成那么多数据,因为那只是您一次可以推入文件的数量。 您将要一遍又一遍地写相同的文本,因此只需使用您第一次创建的原始512k。

Wikipedia非常适合用于混合文本和二进制文件的压缩测试。 如果您需要进行基准比较,那么Hutter奖网站可以为Wikipedia的前100mb提供高水位标记。 当前记录是6.26的比率,即16 mb。

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

  • 为了生成文本,我首先从Mark Gushenbergoff建议的项目gutenberg目录中获取一些文本文件。
  • 我随机选择并下载该子集的一个文档。
  • 然后,按照Noldorin的建议,应用马尔可夫过程,使用下载的文本作为输入。
  • 我以Pike经济的Perl实现为例,用C#编写了新的马尔可夫链。 它一次生成一个单词的文本。
  • 为了提高效率,该代码而不是使用纯马尔可夫链一次生成1gb的文本一个单词,而是生成了〜1mb的随机文本,然后重复获取该文本的随机片段并将它们聚集在一起。

更新 :关于第二个问题,速度-我采用了消除尽可能多的IO的方法,这是在我的5400rpm微型主轴的差劲笔记本电脑上完成的。 这使我完全重新定义了问题-我真正想要的是随机内容,而不是生成带有随机内容的FILE 使用环绕在马尔可夫链上的流,我可以在内存中生成文本并将其流传输到压缩器,从而消除了8g的写入和8g的读取。 对于此特定测试,我不需要验证压缩/解压缩往返行程,因此不需要保留原始内容。 因此,流式传输方法很好地加快了速度。 它节省了80%的时间。

我还没有弄清楚如何进行二进制生成,但是可能很相似。

再次感谢大家提出的所有有益建议。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM