将列表<t>拆分为n个数字</t>的文件

时间:2014-10-28 05:41:41

标签: c# arrays loops streamwriter

我有一个包含超过4000件商品的清单。这些项通过一个以字符串形式返回XML块的方法传递。然后我需要使用StreamWriter将这些字符串写入XML文件。每个文件只允许1000个“字符串”。

int elementCount = 0;
int fileNumber = 1;
string fileName = "C:\\test\\" + DateTime.Now().toString("ddMMyyyy") + "_0" +fileNumber + ".xml";

Do 
{ 
    StreamWriter sw = new StreamWriter(fileName);
    foreach (Vehicles v in vehicles)
    {
        if (elementCount != 1000)
        {
            sw.WriteLine(ConvertCode.ToXml(v));
            elementCount++;
        }
        else
        {
            sw.Close();
            fileNumber++;
            sw = new StreamWriter(fileName);
            elementCount = 0;
            sw.WriteLine(ConvertCode.ToXml(v));
            elementCount++;
            break;
        }
    }
}
while (elementCount < 1000) 

所以在这段代码的最后我希望会有5个文件。包含1000个项目的4个文件和包含项目余额的1个其他文件。在他们的时刻我只得到一个似乎有前500项和最后500项的文件。

我知道我的循环结构一定有问题,但我似乎无法弄清楚如何获得一个成功的结构。感谢

2 个答案:

答案 0 :(得分:0)

我认为文件名错误。在else区块中您有:

sw = new StreamWriter(fileName);

如您所见,您创建新文件而不将文件名更改为新文件(对于新编号)。我想它应该是:

var currDate = DateTime.Now().toString("ddMMyyyy");
string fileName = "C:\\test\\" 
                    + currDate + "_0"
                    + fileNumber + ".xml";
....
else
{
    sw.Close();
    fileNumber++;
    fileName = "C:\\test\\" 
                +  currDate 
                + "_0" + fileNumber 
                + ".xml";
    sw = new StreamWriter(fileName);
    elementCount = 0;
    sw.WriteLine(ConvertCode.ToXml(v));
    elementCount++;
    // break;
    // that break is not neccessary
}

更重要的是,你使用break打破了整个循环(打破了foreach),并再次导致迭代车辆(从开始)。我想这不是必要的。

最后一件事 - 外do...while也不是必要的,我没有看到它的目的。

<强>顺便说一句 这是很好的并行化算法:

var list = vehicles as IList<Vehicle> ?? vehicles.ToList();
if (!list.Any()) return;

var currDate = DateTime.Now().toString("ddMMyyyy");

var groups = list.Count / 1000;
Parallel.For(0, groups + 1, groupNo => {

  var fileName  = "C:\\test\\" 
                +  currDate 
                + "_0" + groupNo
                + ".xml";
  using (var sw = new StreamWriter(fileName))
  {
      var limit = Math.Min(groupNo * 1000 + 1000, list.Count);
      for (var i = groupNo * 1000, i < limit; i++)
      {
          var v = list[i];
          sw.WriteLine(ConvertCode.ToXml(v));
      }
  }

});

答案 1 :(得分:0)

虽然我的代码看起来与您的代码完全不同,但是重新创建您建议修复的代码的fileName的事实。将记住下次这样的小事。

foreach (Vehicle v in vehicles)
{
    if (elementCount < 1000)
    {
        writer.WriteLine(CreateVehicleXmlElement.BuildElement(v));
        elementCount++;
    }
    else if (elementCount == 1000)
    {
         writer.Close();
         fileNumber++;
         elementCount = 0;
         baseName = "c:\\test\\" + DateTime.Now.ToString("ddMMyyy") + "_0" + fileNumber + ".";
         writer = new StreamWriter(baseName + "xml");
         writer.WriteLine("This is the header that will be filled in later");
         writer.WriteLine(CreateVehicleXmlElement.BuildElement(v));
         elementCount++;
    }
}
writer.Close();