注释
常见的数据解析(Json、XML、CSV、二进制)
using System;
using System.IO;
using System.Xml.Serialization;
using Newtonsoft.Json;
using System.Runtime.InteropServices;
using System.Text;
using System.Reflection;
using System.Collections.Generic;
using System.Linq;
/// <summary>
/// 数据解析(Json、XML、CSV、二进制)
/// </summary>
public class AnalyticData
{
#region Json
/// <summary>
/// Json序列化接口
/// </summary>
/// <typeparam name="T">泛型类</typeparam>
/// <param name="dataClass">序列化对象</param>
/// <returns></returns>
public static string JsonSerialization<T>(T dataClass) where T : class
{
string jsonStr = JsonConvert.SerializeObject(dataClass);
return jsonStr;
}
/// <summary>
/// Json反序列化接口
/// </summary>
/// <typeparam name="T">泛型类</typeparam>
/// <param name="path">文件路径</param>
/// <returns></returns>
public static T JsonRead<T>(string path) where T : class
{
T Data;
StreamReader sr = new StreamReader(path);
string jsonStr = sr.ReadToEnd();
//反序列化
Data = JsonConvert.DeserializeObject<T>(jsonStr);
return Data;
}
/// <summary>
/// Json反序列化接口(数组类型)
/// </summary>
/// <typeparam name="T">泛型类</typeparam>
/// <param name="path">文件路径</param>
/// <returns></returns>
public static T[] JsonArrayRead<T>(string path) where T : class
{
T[] DataArray;
StreamReader sr = new StreamReader(path);
string jsonStr = sr.ReadToEnd();
//反序列化
DataArray = JsonConvert.DeserializeObject<T[]>(jsonStr);
return DataArray;
}
/// <summary>
/// Json反序列化接口
/// </summary>
/// <typeparam name="T">泛型类</typeparam>
/// <param name="str">需解析字符串</param>
/// <returns></returns>
public static T JsonByStringRead<T>(string str) where T : class
{
T Data;
//反序列化
Data = JsonConvert.DeserializeObject<T>(str);
return Data;
}
#endregion
#region XML
/// <summary>
/// XML序列化接口
/// </summary>
/// <typeparam name="T">泛型类</typeparam>
/// <param name="dataClass">序列化对象</param>
/// <returns></returns>
public static string XMLSerialization<T>(T dataClass) where T : class
{
using (StringWriter sw = new StringWriter())
{
//此处T必须是Public类型
Type t = dataClass.GetType();
XmlSerializer serializer = new XmlSerializer(dataClass.GetType());
serializer.Serialize(sw, dataClass);
sw.Close();
return sw.ToString();
}
}
/// <summary>
/// XML序列化接口(元素值序列化为单引号格式)
/// </summary>
/// <typeparam name="T">泛型类</typeparam>
/// <param name="dataClass">序列化对象</param>
/// <returns></returns>
public static string XMLToSingleQuotationMarkSerialization<T>(T dataClass) where T : class
{
using (StringWriter sw = new StringWriter())
{
//此处T类必须是Public类型
Type t = dataClass.GetType();
XmlSerializer serializer = new XmlSerializer(dataClass.GetType());
serializer.Serialize(sw, dataClass);
sw.Close();
string dataStr = sw.ToString();
string newDataStr = dataStr.Replace("\"", "'"); //将双引号转换为单引号,方便部分引擎解析
return newDataStr;
}
}
//转义字符:(当属性值中含特殊字符时,为避免解析出错,需使用转义字符)
//1、 < < 小于号
//2、 > > 大于号
//3、 & & 和
//4、 ' ' 单引号
//5、 " " 双引号
//6、 <= <= 小于等于
//7、 >= >= 大于等于
/// <summary>
/// XML反序列化接口
/// </summary>
/// <typeparam name="T">泛型类</typeparam>
/// <param name="path">文件路径</param>
/// <returns></returns>
public static T XMLRead<T>(string path) where T : class
{
StreamReader sReader = new StreamReader(path);
string xmlStr = sReader.ReadToEnd();
try
{
using (StringReader sr = new StringReader(xmlStr))
{
XmlSerializer serializer = new XmlSerializer(typeof(T));
return serializer.Deserialize(sr) as T;
}
}
catch (Exception)
{
return null;
}
}
#endregion
#region CSV
private static char _csvSeparator = ',';
private static bool _trimColumns = false;
//解析一行
private static List<string> ParseLine(string line)
{
StringBuilder _columnBuilder = new StringBuilder();
List<string> Fields = new List<string>();
bool inColum = false; //是否是在一个列元素里
bool inQuotes = false; //是否需要转义
bool isNotEnd = false; //读取完毕未结束转义
_columnBuilder.Remove(0, _columnBuilder.Length);
//空行也是一个空元素,一个逗号是2个空元素
if (line == "")
{
Fields.Add("");
}
// Iterate through every character in the line 遍历行中的每个字符
for (int i = 0; i < line.Length; i++)
{
char character = line[i];
//If we are not currently inside a column 如果我们现在不在一列中
if (!inColum)
{
// If the current character is a double quote then the column value is contained within
//如果当前字符是双引号,则列值包含在内
// double quotes, otherwise append the next character
//双引号,否则追加下一个字符
inColum = true;
if (character == '"')
{
inQuotes = true;
continue;
}
}
// If we are in between double quotes 如果我们处在双引号之间
if (inQuotes)
{
if ((i + 1) == line.Length) //这个字符已经结束了整行
{
if (character == '"') //正常转义结束,且该行已经结束
{
inQuotes = false;
continue;
}
else //异常结束,转义未收尾
{
isNotEnd = true;
}
}
else if (character == '"' && line[i + 1] == _csvSeparator) //结束转义,且后面有可能还有数据
{
inQuotes = false;
inColum = false;
i++; //跳过下一个字符
}
else if (character == '"' && line[i + 1] == '"') //双引号转义
{
i++; //跳过下一个字符
}
else if (character == '"') //双引号单独出现(这种情况实际上已经是格式错误,为了兼容暂时不处理)
{
throw new System.Exception("格式错误,错误的双引号转义");
}
//其他情况直接跳出,后面正常添加
}
else if (character == _csvSeparator)
{
inColum = false;
}
// If we are no longer in the column clear the builder and add the columns to the list
/// 结束该元素时inColumn置为false,并且不处理当前字符,直接进行Add
if (!inColum)
{
Fields.Add(_trimColumns ? _columnBuilder.ToString().Trim() : _columnBuilder.ToString());
_columnBuilder.Remove(0, _columnBuilder.Length);
}
else //追加当前列
{
_columnBuilder.Append(character);
}
}
// If we are still inside a column add a new one (标准格式一行结尾不需要逗号结尾,而上面for是遇到逗号才添加的,为了兼容最后还要添加一次)
if (inColum)
{
if (isNotEnd)
{
_columnBuilder.Append("\r\n");
}
Fields.Add(_trimColumns ? _columnBuilder.ToString().Trim() : _columnBuilder.ToString());
}
else //如果inColumn为false,说明已经添加,因为最后一个字符为分隔符,所以后面要加上一个空元素
{
Fields.Add("");
}
return Fields;
}
/// <summary>
/// 读取CSV文件
/// </summary>
/// <param name="filePath"></param>
/// <param name="encoding"></param>
/// <returns></returns>
public static List<List<string>> CSVRead(string filePath, Encoding encoding)
{
List<List<string>> result = new List<List<string>>();
string content = File.ReadAllText(filePath, encoding); //读取所有的文本内容
string[] lines = content.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);
//以换行回车拆分字符串,去除空格
//注:回车换行可能对某些文本不适用,这里如果我们出现读取不正常,可以改用 \n (换行)试试
for (int i = 0; i < lines.Length; i++)
{
List<string> line = ParseLine(lines[i]);
result.Add(line);
}
return result;
}
/// <summary>
/// 生成CSV文件
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="dataList">对象集合</param>
/// <param name="filePath">文件存储路径</param>
/// <returns></returns>
public static bool CSVFileSaveData<T>(List<T> dataList, string filePath) where T : class
{
bool successFlag = true;
//所有文本
StringBuilder sb_Text = new StringBuilder();
//第一行属性文本
StringBuilder strColumn = new StringBuilder();
//其他行属性值文本
StringBuilder strValue = new StringBuilder();
StreamWriter sw = null;
var tp = typeof(T);
//获取当前Type的所有公共属性 BindingFlags指定反射查找的范围
PropertyInfo[] props = tp.GetProperties(BindingFlags.Public | BindingFlags.Instance);
try
{
//获取第一行属性文本
for (int i = 0; i < props.Length; i++)
{
var itemPropery = props[i];
//检索自定义特性信息
AttrForCsvColumnLabel labelAttr = itemPropery.GetCustomAttributes(typeof(AttrForCsvColumnLabel), true).FirstOrDefault() as AttrForCsvColumnLabel;
if (labelAttr != null)
{
strColumn.Append(labelAttr.Title);
}
else
{
strColumn.Append(props[i].Name);
}
strColumn.Append(",");
}
//移除最后一个","
strColumn.Remove(strColumn.Length - 1, 1);
sb_Text.AppendLine(strColumn.ToString());
//依次遍历数据列表,得到其他行属性值文本
for (int i = 0; i < dataList.Count; i++)
{
var model = dataList[i];
strValue.Clear();
//获取每一组数据中对应的属性值
for (int m = 0; m < props.Length; m++)
{
var itemProoery = props[m];
var val = itemProoery.GetValue(model, null);
if (m == 0)
{
strValue.Append(val);
}
else
{
strValue.Append(",");
strValue.Append(val);
}
}
sb_Text.AppendLine(strValue.ToString());
}
}
catch (System.Exception)
{
successFlag = false;
}
finally
{
if (sw != null)
{
sw.Dispose();
}
}
File.WriteAllText(filePath, sb_Text.ToString(), Encoding.Default);
return successFlag;
}
public static void CsvWrite(List<List<string>> datas, string path)
{
//所有文本
StringBuilder sb_Text = new StringBuilder();
for (int i = 0; i < datas.Count; i++)
{
for (int j = 0; j < datas[i].Count; j++)
{
sb_Text.Append(datas[i][j] + ",");
}
sb_Text.AppendLine();
}
File.WriteAllText(path, sb_Text.ToString(), Encoding.Default);
}
#endregion
#region 结构体二进制
/// <summary>
/// 结构体转换为二进制数组
/// </summary>
/// <param name="structObj">结构体</param>
/// <returns>转换后的二进制数组</returns>
public static byte[] StructToBytesFunc(object structObj)
{
//得到结构体的大小
int size = Marshal.SizeOf(structObj);
//创建byte数组
byte[] bytes = new byte[size];
//分配结构体大小的内存空间
IntPtr structPtr = Marshal.AllocHGlobal(size);
//将结构体拷贝到分配的内存空间
Marshal.StructureToPtr(structObj, structPtr, false);
//从内存空间拷贝到byte数组
Marshal.Copy(structPtr, bytes, 0, size);
//释放内存空间
Marshal.FreeHGlobal(structPtr);
//返回byte数组
return bytes;
}
/// <summary>
/// byte数组转结构
/// </summary>
/// <param name="bytes">byte数组</param>
/// <param name="type">结构类型</param>
/// <returns>转换后的结构</returns>
public static object BytesToStructFunc(byte[] bytes, Type type)
{
int size = Marshal.SizeOf(type);
//byte数组长度小于结构的大小
if (size > bytes.Length)
{
//返回空
return null;
}
//分配结构大小的内存空间
IntPtr structPtr = Marshal.AllocHGlobal(size);
//将byte数组拷贝到分配好的内存空间
Marshal.Copy(bytes, 0, structPtr, size);
//将内存空间转换为目标结构
object obj = Marshal.PtrToStructure(structPtr, type);
//释放内存空间
Marshal.FreeHGlobal(structPtr);
//返回结构
return obj;
}
#endregion
}
public class AttrForCsvColumnLabel : Attribute
{
public string Title { get; set; }
}