如何阅读大文本文件并将其分成批处理?

时间:2014-09-18 19:38:59

标签: c# text-files batch-processing

我有一个大文本文件,其中包含我将用于加载到我尝试创建的自定义应用程序中的GUID。由于文件太大(可能包含数百万行GUID),我想将其分成几部分并处理每个部分,然后移动到下一部分,直到文件结束。

文本文件示例

ASDFSADFJO23490234AJSDFKL
JOGIJO349230420GJDGJDO230
BJCIOJDFOBJOD239402390423
JFWEIOJFOWE2390423901230N
3490FJSDOFOIWEMO23MOFI23O
FJWEIOFJWEIOFJOI23J230022

让我们说,文本文件有99,000行,我想处理前10,000个值(重复到结束)。我将使用DateTime.Now作为文件夹名称为第一批10,000创建一个新文件夹。然后,10,000个值将使用其值名称作为文件名创建文件。完成前10,000个值后,我将再次使用DateTime.Now创建一个新文件夹,然后移动到文本文件中的下一个10,000个值。重复直到文件结束。

我能够读取文本文件,使用DateTime.Now创建文件夹,使用适当的名称创建文件,但我不知道如何批处理文本文件中的值列表。

这就是我阅读文件的方式。

string[] source = new string[] {}; 
source = File.ReadAllLines(@"C:\guids.txt");

我尝试使用Skip / Take方法,我认为它有效吗?但我只是不知道如何创建一个新文件夹并添加新的子集。任何帮助将不胜感激。我愿意接受建议,如果您需要更多详细信息,可以帮助澄清。谢谢!

1 个答案:

答案 0 :(得分:1)

从评论中我推断出你的问题实际上并不是“如何批量读取guid.txt?”,而是“如何处理这些guid并在单独的文件夹中以万个为一组创建文件” 。 考虑到这一点,这里有一个如何做到这一点的例子。

var batchSize = 10000;
var source = File.ReadLines(@"C:\guids.txt");
var i = 0;
var currentDirPath = "";
foreach (var line in source)
{
    if (i % batchSize == 0)
    {
        currentDirPath = Path.GetRandomFileName();
        Directory.CreateDirectory(currentDirPath);
    }
    var newFile = Path.Combine(currentDirPath, line + ".txt");
    File.WriteAllText(newFile, "Some content");
    i++;
}

避免将DateTime用于文件或文件夹名称。一些不可预见的行为使您的代码尝试写入已存在的文件的可能性太大。

编辑:关于并行性:仅在需要时使用它。 总是比看起来更复杂,并且它倾向于引入难以找到的塞子。话虽如此,这是一个未经测试的想法。

//Make sure the current folder is empty, otherwise the folders are very likely to already exist.
if (Directory.GetFiles(Directory.GetCurrentDirectory()).Any())
{
    throw new IOException("Current directory is not empty.");
}

var batchSize = 10000;
var source = File.ReadAllLines(@"C:\guids.txt");

//Create the folders synchronoulsy to avoid race conditions.
var batchCount = (source.Length/batchSize) + 1;
for (int i = 0; i < batchCount; i++)
{
    Directory.CreateDirectory(i.ToString());
}

source.AsParallel().ForAll(line =>
{
    var folder = ((int)(Array.IndexOf(source, line) / batchSize)).ToString();
    var newFile = Path.Combine(folder.ToString(), line + ".txt");
    File.WriteAllText(newFile, "Some content");
});