注释
常见的数据解析(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 CSVprivate 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,并且不处理当前字符,直接进行Addif (!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; }
}