我对c#中的编程很陌生,我在将几个csv文件中的大量数据处理成一个xml文件时遇到了一些问题。
csv文件我看起来如下:
"ID","NODE","PROCESS_STATE","TIME_STAMP","PREV_TIME_STAMP","CALCULATED"
206609474,2175,47,31.03.2015 00:01:25,31.03.2015 00:01:24,1
206609475,2175,47,31.03.2015 00:02:25,31.03.2015 00:01:25,1
206609476,2175,47,31.03.2015 00:03:25,31.03.2015 00:02:25,1
在第一步中,我删除了对我的计算不重要的所有条目(例如,我删除了所有不包含特定日期的文件),然后再次保存每个文件。
第二步是将所有准备好的文件(~100)合并到一个大的csv文件中。
直到这里一切都运行良好而且快速。
最后一步是将csv文件转换为以下格式的xml文件:
<data-set>
<PDA_DATA>
<ID>484261933</ID>
<NODE>2190</NODE>
<PROCESS_STATE>18</PROCESS_STATE>
<PREV_TIME_STAMP>05.05.2016 22:53:41</PREV_TIME_STAMP>
</PDA_DATA>
<PDA_DATA>
<ID>484261935</ID>
<NODE>2190</NODE>
<PROCESS_STATE>47</PROCESS_STATE>
<PREV_TIME_STAMP>06.05.2016 00:44:17</PREV_TIME_STAMP>
</PDA_DATA>
</data-set>
如您所见,我删除元素(“TIME_STAMP”,“CALCULATED”)以及更多我还删除条目“TIME_STAMP”等于“PREV_TIME_STAMP”的所有条目。我正在使用以下代码执行此操作:
string[] csvlines = File.ReadAllLines("All_Machines.csv");
XElement xml = new XElement("data-set",
from str in csvlines
let columns = str.Split(',')
select new XElement("PDA_DATA",
new XElement("ID", columns[0]),
new XElement("NODE", columns[2]),
new XElement("PROCESS_STATE", columns[5]),
new XElement("TIME_STAMP", columns[6]),
new XElement("PREV_TIME_STAMP", columns[9]),
new XElement("CALCULATED", columns[10])));
// Remove unneccessray elements
xml.Elements("PDA_DATA")
.Where(e =>
e.Element("TIME_STAMP").Value.Equals(e.Element("PREV_TIME_STAMP").Value))
.Remove(); // Remove entries with duration = 0
xml.Elements("PDA_DATA").Elements("TIME_STAMP").Remove();
xml.Elements("PDA_DATA").Elements("PREV_PROCESS_STATE").Remove();
xml.Elements("PDA_DATA").Elements("CALCULATED").Remove();
xml.Save("All_Machines.xml");
这是我的问题。如果我排除我删除元素的行,其中TimeStamp等于PrevTimeStamp,一切都运行良好和快速。 但是使用此命令,它需要花费大量时间,并且仅适用于小型csv文件。
我对资源节约型编程一无所知,所以如果有人能告诉我问题在哪里或者如何做得更好,我会很高兴。
答案 0 :(得分:0)
这样做得更快:
string[] csvlines = File.ReadAllLines("All_Machines.csv");
XElement xml = new XElement("data-set",
from str in csvlines
let columns = str.Split(',')
select new XElement("PDA_DATA",
new XElement("ID", columns[0]),
new XElement("NODE", columns[1]),
new XElement("PROCESS_STATE", columns[2]),
new XElement("TIME_STAMP", columns[3]),
new XElement("PREV_TIME_STAMP", columns[4]),
new XElement("CALCULATED", columns[5]),
)
);
// Remove unneccessray elements
XElement xml2 = new XElement("data-set",
from el in xml.Elements()
where (el.Element("TIME_STAMP").Value != (el.Element("PREV_TIME_STAMP").Value))
select el
);
xml2.Elements("PDA_DATA").Elements("TIME_STAMP").Remove();
xml2.Elements("PDA_DATA").Elements("PREV_PROCESS_STATE").Remove();
xml2.Elements("PDA_DATA").Elements("CALCULATED").Remove();
xml2.Save("All_Machines.xml");
仍然不适合超过150 MB的csv文件大小..还有更好的建议吗?
答案 1 :(得分:0)
使用Cinchoo ETL - 一个开源框架,您可以使用以下几行代码快速读取和写入CSV / Xml大文件
using (var csv = new ChoCSVReader("NodeData.csv").WithFirstLineHeader(true)
.WithFields("ID", "NODE", "PROCESS_STATE", "PREV_TIME_STAMP"))
{
using (var xml = new ChoXmlWriter("NodeData.xml").WithXPath("data-set/PDA_DATA"))
xml.Write(csv);
}
输出xml看起来像
<data-set>
<PDA_DATA>
<ID>206609474</ID>
<NODE>2175</NODE>
<PROCESS_STATE>47</PROCESS_STATE>
<PREV_TIME_STAMP>31.03.2015 00:01:25</PREV_TIME_STAMP>
</PDA_DATA>
<PDA_DATA>
<ID>206609475</ID>
<NODE>2175</NODE>
<PROCESS_STATE>47</PROCESS_STATE>
<PREV_TIME_STAMP>31.03.2015 00:02:25</PREV_TIME_STAMP>
</PDA_DATA>
<PDA_DATA>
<ID>206609476</ID>
<NODE>2175</NODE>
<PROCESS_STATE>47</PROCESS_STATE>
<PREV_TIME_STAMP>31.03.2015 00:03:25</PREV_TIME_STAMP>
</PDA_DATA>
</data-set>
披露:我是这个图书馆的作者