注释
常见的数据解析(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; } }
复制