常见的数据解析(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;
///
/// 数据解析(Json、XML、CSV、二进制)
///
public class AnalyticData
{
#region Json
///
/// Json序列化接口
///
/// 泛型类
/// 序列化对象
///
public static string JsonSerialization(T dataClass) where T : class
{
string jsonStr = JsonConvert.SerializeObject(dataClass);
return jsonStr;
}
///
/// Json反序列化接口
///
/// 泛型类
/// 文件路径
///
public static T JsonRead(string path) where T : class
{
T Data;
StreamReader sr = new StreamReader(path);
string jsonStr = sr.ReadToEnd();
//反序列化
Data = JsonConvert.DeserializeObject(jsonStr);
return Data;
}
///
/// Json反序列化接口(数组类型)
///
/// 泛型类
/// 文件路径
///
public static T[] JsonArrayRead(string path) where T : class
{
T[] DataArray;
StreamReader sr = new StreamReader(path);
string jsonStr = sr.ReadToEnd();
//反序列化
DataArray = JsonConvert.DeserializeObject(jsonStr);
return DataArray;
}
///
/// Json反序列化接口
///
/// 泛型类
/// 需解析字符串
///
public static T JsonByStringRead(string str) where T : class
{
T Data;
//反序列化
Data = JsonConvert.DeserializeObject(str);
return Data;
}
#endregion
#region XML
///
/// XML序列化接口
///
/// 泛型类
/// 序列化对象
///
public static string XMLSerialization(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();
}
}
///
/// XML序列化接口(元素值序列化为单引号格式)
///
/// 泛型类
/// 序列化对象
///
public static string XMLToSingleQuotationMarkSerialization(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、 >= >= 大于等于
///
/// XML反序列化接口
///
/// 泛型类
/// 文件路径
///
public static T XMLRead(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 ParseLine(string line)
{
StringBuilder _columnBuilder = new StringBuilder();
List Fields = new List();
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;
}
///
/// 读取CSV文件
///
///
///
///
public static List> CSVRead(string filePath, Encoding encoding)
{
List> result = new List>();
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 line = ParseLine(lines[i]);
result.Add(line);
}
return result;
}
///
/// 生成CSV文件
///
///
/// 对象集合
/// 文件存储路径
///
public static bool CSVFileSaveData(List 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> 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 结构体二进制
///
/// 结构体转换为二进制数组
///
/// 结构体
/// 转换后的二进制数组
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;
}
///
/// byte数组转结构
///
/// byte数组
/// 结构类型
/// 转换后的结构
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; }
}