随机化真正巨大的文本文件的行

idi*_*ous 11 c# memory performance file-io

我想将文件中的行随机化,该文件包含超过3200万行10位数字符串.我知道如何使用它,File.ReadAllLines(...).OrderBy(s => random.Next()).ToArray()但这不是内存效率,因为它将所有内容加载到内存(超过1.4GB),只适用于x64架构.

另一种方法是拆分它并随机化较短的文件然后合并它们但我想知道是否有更好的方法来做到这一点.

Bal*_*ick 1

该应用程序使用字节数组演示了您想要的内容

  1. 它创建一个带有填充数字 0 到 32000000 的文件。
  2. 它加载文件,然后使用块复制 Fisher-Yates 方法将它们在内存中打乱。
  3. 最后,它按打乱的顺序将文件写回

峰值内存使用量约为 400 MB。在我的机器上运行大约 20 秒(主要是文件 IO)。

public class Program
{
    private static Random random = new Random();

    public static void Main(string[] args)
    {
        // create massive file
        var random = new Random();
        const int lineCount = 32000000;

        var file = File.CreateText("BigFile.txt");

        for (var i = 0; i < lineCount ; i++)
        {
            file.WriteLine("{0}",i.ToString("D10"));
        }

        file.Close();

        int sizeOfRecord = 12;

        var loadedLines = File.ReadAllBytes("BigFile.txt");

        ShuffleByteArray(loadedLines, lineCount, sizeOfRecord);

        File.WriteAllBytes("BigFile2.txt", loadedLines);
    }

    private static void ShuffleByteArray(byte[] byteArray, int lineCount, int sizeOfRecord)
    {
        var temp = new byte[sizeOfRecord];

        for (int i = lineCount - 1; i > 0; i--)
        {
            int j = random.Next(0, i + 1);
            // copy i to temp
            Buffer.BlockCopy(byteArray, sizeOfRecord * i, temp, 0, sizeOfRecord);
            // copy j to i
            Buffer.BlockCopy(byteArray, sizeOfRecord * j, byteArray, sizeOfRecord * i, sizeOfRecord);
            // copy temp to j
            Buffer.BlockCopy(temp, 0, byteArray, sizeOfRecord * j, sizeOfRecord);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)