标题太难起了。这个功能的由来就是有的时候我们会根据外部的文件,将文件中的数据按要求导入到数据库中。在本人最近几个月的工作中至少碰到三次了(一次xml文件,一次文本文件,这一次是csv格式的),xml文件的操作比较容易(您可以参考笔者之前的这一篇),对于txt或者csv等格式的文件觉得有必要写一个通用的方法,实现文件内容的快速有效的解析。下面记录一下这个方法,您可以根据自己的需要适当修改成自己想要的形式。
1、读入文件
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
private const string fileType = "csv";
/// <summary>
/// 从fileupload控件中读出文件内容(csv,txt等格式)
/// </summary>
/// <param name="txtFileName"></param>
/// <param name="data"></param>
/// <returns></returns>
public static string GetFileContent(string fileName, byte[] data)
{
string fileContent = string.Empty;
string[] strArr = fileName.Split('.');
if (string.Compare(strArr[strArr.Length - 1].ToUpper(), fileType.ToUpper()) != 0)
{
throw new FormatException("必须是(." + fileType + ")格式的文件");
}
else
{
try
{
fileContent = System.Text.Encoding.GetEncoding("GB2312").GetString(data, 0, data.Length); //二进制数组转化为字符串
}
catch (Exception ex)
{
throw ex;
}
}
return fileContent;
}
/// <summary>
/// 从fileupload控件中读出文件内容(csv,txt等格式)
/// </summary>
/// <param name="txtFileName"></param>
/// <param name="data"></param>
/// <returns></returns>
public static string GetFileContent(string fileName, byte[] data)
{
string fileContent = string.Empty;
string[] strArr = fileName.Split('.');
if (string.Compare(strArr[strArr.Length - 1].ToUpper(), fileType.ToUpper()) != 0)
{
throw new FormatException("必须是(." + fileType + ")格式的文件");
}
else
{
try
{
fileContent = System.Text.Encoding.GetEncoding("GB2312").GetString(data, 0, data.Length); //二进制数组转化为字符串
}
catch (Exception ex)
{
throw ex;
}
}
return fileContent;
}
2、解析文件成实体
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
public static IList<T> ConvertFile2Model<T>(IList<IList<string>> listStr, IList<string> listProperty) where T : class, new()
{
IList<T> listModel = new List<T>();
//通过反射 显示要显示的列
BindingFlags bf = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static;//反射标识
T model = default(T);
Type objType = typeof(T);
PropertyInfo[] propInfoArr = objType.GetProperties(bf);
foreach (IList<string> listItem in listStr)
{
model = new T();
int len = listItem.Count;
if (listProperty.Count != len)
{
throw new Exception("属性和要解析的列数量不等");
}
for (int i = 0; i < len; i++)
{
string property = listProperty[i];
foreach (PropertyInfo item in propInfoArr)
{
if (string.Compare(property.Trim().ToUpper(), item.Name.ToUpper()) == 0)
{
item.SetValue(model, listItem[i], null);
break;
}
}
}
listModel.Add(model);
}
return listModel;
}
{
IList<T> listModel = new List<T>();
//通过反射 显示要显示的列
BindingFlags bf = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static;//反射标识
T model = default(T);
Type objType = typeof(T);
PropertyInfo[] propInfoArr = objType.GetProperties(bf);
foreach (IList<string> listItem in listStr)
{
model = new T();
int len = listItem.Count;
if (listProperty.Count != len)
{
throw new Exception("属性和要解析的列数量不等");
}
for (int i = 0; i < len; i++)
{
string property = listProperty[i];
foreach (PropertyInfo item in propInfoArr)
{
if (string.Compare(property.Trim().ToUpper(), item.Name.ToUpper()) == 0)
{
item.SetValue(model, listItem[i], null);
break;
}
}
}
listModel.Add(model);
}
return listModel;
}
在上面的方法中,我们还需要用到两个辅助方法,贴出来:
(1)获取实体属性
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
public static IList<string> CreateModelProperty<T>() where T : class, new()
{
IList<string> listProperty = new List<string>();
BindingFlags bf = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static;//反射标识
Type objType = typeof(T);
PropertyInfo[] propInfoArr = objType.GetProperties(bf);
foreach (PropertyInfo item in propInfoArr)
{
listProperty.Add(item.Name);
}
return listProperty;
}
{
IList<string> listProperty = new List<string>();
BindingFlags bf = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static;//反射标识
Type objType = typeof(T);
PropertyInfo[] propInfoArr = objType.GetProperties(bf);
foreach (PropertyInfo item in propInfoArr)
{
listProperty.Add(item.Name);
}
return listProperty;
}
(2)、解析文件内容成特定的形式
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
public static IList<IList<string>> CreateFileContentArr(string fileContent)
{
IList<IList<string>> listStr = new List<IList<string>>();
if (!string.IsNullOrEmpty(fileContent))
{
fileContent = fileContent.Trim();
string[] strArr = fileContent.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);//换行符 一行记录对应一个实体记录
foreach (string item in strArr)
{
IList<string> listChild = new List<string>();
string[] strChildren = item.Split(',');//以逗号,分隔 可以是其他类型的符号,看具体需要
foreach (string strItem in strChildren)
{
listChild.Add(strItem);
}
listStr.Add(listChild);
}
}
return listStr;
}
{
IList<IList<string>> listStr = new List<IList<string>>();
if (!string.IsNullOrEmpty(fileContent))
{
fileContent = fileContent.Trim();
string[] strArr = fileContent.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);//换行符 一行记录对应一个实体记录
foreach (string item in strArr)
{
IList<string> listChild = new List<string>();
string[] strChildren = item.Split(',');//以逗号,分隔 可以是其他类型的符号,看具体需要
foreach (string strItem in strChildren)
{
listChild.Add(strItem);
}
listStr.Add(listChild);
}
}
return listStr;
}
ps: 解析文件成特定的形式,是按照给出的文件自定义解析。您可以抽象出变化点(比如分隔符等),让它更加通用。示例中我是按照手头的项目需要解析的,懒人一个,不费事了,不打酱油打麻将去也。
demo下载:demo