Get your free 500MB here: http://folders.live.com
And let us know what you think
(北京时间6/28/2007, 9:30AM, 刚经朋友提醒查明:中国区服务尚未开通,我faint...)
更新:谢谢aspnetx提供的方法:中国区的用户“在你的IE浏览器把英语-美国[en-US]设置成默认语言就可以”
(但至少还可以下载吧,比如:http://folders.live.com/self.aspx/FXxXLAw2eAI/Public/%e6%9a%97%e6%81%8b%e6%83%85%e4%b9%a6(%e4%bf%9e%e6%80%9d%e8%bf%9c_BiZ%e4%b9%90%e5%9b%a2).mp3)
前些天正好需要处理一些csv文件(就是逗号分隔文件,常用excel的应该很熟悉),于是想早早.NET里是不是已经有这样的类库了。最后还真的发现了一个。不过有趣的是那个类(Microsoft.VisualBasic.FileIO.TextFieldParser)只有VB.NET的版本。
不过我们是在.NET平台上么,CLR的好处不是只拿来吹吹的。VB.NET写的类,在C#程序里一样能用:
1. 首先Add Refenece(Microsoft.VisualBasic):
2. 然后声明使用的namespace:
using Microsoft.VisualBasic;
3. 接着就可以写代码了, 我加了一些很简单的Schema的功能:
using Microsoft.VisualBasic.FileIO;
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
namespace MS.Live.Cumulus.Autopilot.Watchdog
{
public class CsvParser
{
/* fields */
TextFieldParser csvParser = null;
Dictionary<string, int> textSchema = null;
/* methods */
public CsvParser(string inputFile)
{
csvParser = new TextFieldParser(inputFile);
csvParser.TextFieldType = FieldType.Delimited;
csvParser.Delimiters = new string[] { "," };
}
public CsvParser(Stream inputStream)
{
csvParser = new TextFieldParser(inputStream);
csvParser.TextFieldType = FieldType.Delimited;
csvParser.Delimiters = new string[] { "," };
}
public void SetSchema(string[] schema)
{
textSchema = new Dictionary<string, int>(schema.Length);
int index = 0;
foreach (string field in schema)
textSchema.Add(field, index++); // may throw an exception if duplicated field names exist in schema
}
public string ReadLineRaw()
{
return csvParser.ReadLine();
}
public string[] ReadLine()
{
return csvParser.ReadFields();
}
public string[] ReadFields(string[] filter)
{
if (null == textSchema)
throw new Exception("The parser has no schema defined.");
string[] allFields = ReadLine();
string[] result = new string[filter.Length];
for (int i = 0; filter.Length > i; i++)
result[i] = allFields[textSchema[filter[i]]];
return result;
}
/* properties */
public bool IsEndOfData
{
get { return csvParser.EndOfData; }
}
}
4. 最后测试一下:
public void TestCsvParser()
{
CsvParser parser = new CsvParser("input.csv");
try
{
parser.ReadFields(new string[] { "Address" });
Assert.Fail("This line should not be reached");
}
catch (Exception)
{
}
parser.SetSchema(new string[]{ "Name", "PhoneNumber", "Address" });
string[] row = parser.ReadLine();
Assert.IsTrue("FakeID1" == row[0] && "FakePhoneNumber1" == row[1] && "FakeAddress1" == row[2]);
Assert.IsTrue("FakeID2,FakePhoneNumber2,FakeAddress2" == parser.ReadLineRaw());
row = parser.ReadFields(new string[]{ "Address", "Name" });
Assert.IsTrue(2 == row.Length && "FakeAddress3" == row[0] && "FakeID3" == row[1]);
row = parser.ReadFields(new string[]{ "Name", "PhoneNumber", "Address" });
row = parser.ReadFields(new string[]{ "Name", "PhoneNumber", "Address" });
Assert.IsTrue(3 == row.Length && "FakeID5" == row[0] && "hello,Fake\"PhoneNumber5" == row[1] && "FakeAddress5" == row[2]);
Assert.IsTrue(true == parser.IsEndOfData);
}
测试的输入文件如下:
FakeID1,FakePhoneNumber1,FakeAddress1
FakeID2,FakePhoneNumber2,FakeAddress2
FakeID3 , FakePhoneNumber3,FakeAddress3
FakeID4, FakePhoneNumber4 ,FakeAddress4
FakeID5, "hello,Fake""PhoneNumber5", FakeAddress5