为了测试压缩的目的,我需要能够创建大文件,最好是在文本,二进制,和混合格式。
- 这些文件的内容既不是完全随机的,也不均匀。
全零的二进制文件是不行的。 与完全随机数据的二进制文件也并不好。 对于文本,用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存有通过一个StreamWriter,并多次发出到文本文件中。 含量非随机的和非均匀的,但它确实有许多相同的重复块,这是不自然的。 此外,因为的Lorem Ispum块是如此之小(<1K),它需要许多循环和一个非常,非常长的时间。
这些都不是我比较满意的。
我已经看到了答案, 快速创建一个Windows系统上的大文件? 。 这些方法是非常快的,但我认为他们只需填写文件用零或随机数据,这两者都不是我想要的。 我有运行像重叠群或FSUTIL外部进程,如果必要的话没有问题。
测试在Windows上运行。
而不是创建新的文件,它更有意义只使用已经在文件系统中存在的文件? 我不知道有什么是足够大的。
有关启动与单个现有文件什么(也许C:\ WINDOWS \ Microsoft.NET \框架\ V2.0.50727 \ CONFIG \ enterprisesec.config.cch一个文本文件),并复制其内容多少次? 这将有一个文本或二进制文件的工作。
目前,我有一个办法,这类作品,但需要很长时间才能运行。
有没有其他人解决了这个?
有没有写一个文本文件不是通过StreamWriter的一个更快的方法?
建议?
编辑 :我喜欢马尔可夫链产生更自然的文本的想法。 仍然需要面对速度的问题,但。
我想你可能会寻找类似一个马尔可夫链过程来产生这个数据。 它既是随机的(随机),而且层次分明,在它所操作基于对有限状态机 。
事实上,马尔可夫链已被用于生成人类的语言半逼真的文本。 在一般情况下,他们没有琐碎的事情需要正确地分析,但他们表现出某些特性的事实应该是配不上你。 (同样,见马尔可夫链的属性页的部分。)希望你会看到如何设计一个,但是-来实现,它实际上是一个相当简单的概念。 您最好的选择可能会创建一个通用的马尔可夫过程的框架,然后才能分析无论是自然语言或源代码(无论你希望你的随机数据来模拟)“训练”你的马尔可夫过程。 最终,这应该给你非常高质量的数据在你的需求方面。 非常值得去努力,如果你需要的测试数据,这些巨大的长度。
对于文本,您可以使用堆栈溢出社区转储 ,有数据存在的300megs。 虽然这会花大约6分钟加载到与我写的,可能大约在同一时间转储所有的职位,以文本文件,这很容易给你200K之间的任何地方,以1个万元的文本文件,这取决于你的方法应用分贝(与具有源和xml的额外的好处混合)。
你也可以使用类似维基百科转储 ,似乎在MySQL格式这将使它的超级容易的工作船。
如果你正在寻找一个大的文件,您可以拆分为二进制的场合,你既可以使用一个虚拟机VMDK或DVD本地撕开。
编辑
马克提到了古腾堡计划下载,这也是文本(和音频)一个很好的来源,可以通过BitTorrent的下载 。
你总是可以编写自己一点网络爬虫...
UPDATE冷静的家伙,这将是一个很好的答案, 如果他没有说,他已经有了一个解决方案,“时间太长”。
快速检查这里似乎表明,下载的东西8GB将需要相当长的时间。
我认为,在Windows目录或许会成为一个足够好的来源为您的需要。 如果你的文字后,我将通过各找txt文件,并通过循环并根据需要可以得到正确的大小的文件将它们复制到输出文件多次目录的递归。
然后,您可以通过寻找.EXE文件或.DLL文件使用二进制文件一个类似的做法。
对于文本文件,你可能有一些成功服用英语单词列表 ,只是在随机从它拉动的话。 这不会产生真正的英文文本,但我猜它会产生类似于您可能会发现英语里的一封信的频率。
对于更结构化的方法,你可以使用一个马尔可夫链培训了一些大型的免费英文文本。
你为什么不只是采取Lorem存有和你的输出前在内存中创建一个长字符串。 文本应在O(log n)的,如果你双击文本的数量,你每次都的扩张速度。 你甚至可以计算数据的总长度前手让你不能从有到内容复制到一个新的字符串/数组受苦。
由于您的缓冲区只有512K或任何你将其设置为,你只需要编写之前产生如此多的数据,因为这是唯一可以在同一时间推到文件的数量。 您将要一遍又一遍地写相同的文字,所以只需使用您所创建的第一次原来的512K。
维基百科是优秀的混合文本和二进制压缩试验。 如果你需要的基准比较, 胡特奖网站可以为维基百科的第一100MB提供一个高水位标记。 当前记录是一个6.26比,16 MB。
感谢所有的快速输入。 我决定单独考虑速度和“自然”的问题。 对于自然十岁上下文字的产生,我已经联合了几个想法。
- 要生成的文字,我开始从几个文本文件Gutenberg项目目录,由Mark Rushakoff的建议。
- 我随机选择并下载子集的一个文件。
- 然后我申请一个马尔可夫过程,如通过Noldorin建议 ,使用下载的文本输入。
- 我使用了一个新马尔可夫链在C# 派克的经济Perl实现作为一个例子。 它同时生成一个文本一个字。
- 为了提高效率,而不是使用纯马尔可夫链在一个时间,以产生一个文本字的1GB,代码生成〜1MB的随机文本,然后反复利用了该随机段和水珠在一起。
更新 :至于第二个问题,速度-我把消除尽可能多的IO尽可能的办法,这是被我的可怜的笔记本采用了5400转的迷你主轴进行。 这使我完全重新定义问题-而不是生成一个文件 ,随机内容,我真正想要的是随机的内容。 使用周围马尔可夫链包裹流,我可以在内存中生成文本,并流至压缩机,从而消除了写入和读出8克8克。 对于这个特殊的测试,我并不需要验证的压缩/解压缩往返,所以我不需要保留原来的内容。 所以流的方式运作良好,大规模加快速度。 它切成所需要的时间的80%。
我还没有想出如何做二进制的产生,但它可能会是一些类似。
谢谢大家,再次对所有有用的思路。
文章来源: How can I quickly create large (>1gb) text+binary files with “natural” content? (C#)