标题太难起了。这个功能的由来就是有的时候我们会根据外部的文件,将文件中的数据按要求导入到数据库中。在本人最近几个月的工作中至少碰到三次了(一次xml文件,一次文本文件,这一次是csv格式的),xml文件的操作比较容易(您可以参考笔者之前的这一篇),对于txt或者csv等格式的文件觉得有必要写一个通用的方法,实现文件内容的快速有效的解析。下面记录一下这个方法,您可以根据自己的需要适当修改成自己想要的形式。
1、读入文件
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![ExpandedBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.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://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![ExpandedBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.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://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![ExpandedBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.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://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![ExpandedBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.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