注釋
常見的數(shù)據(jù)解析(Json、XML、CSV、二進(jìn)制)文章來源地址http://www.zghlxwxcb.cn/news/detail-832578.html
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>
/// 數(shù)據(jù)解析(Json、XML、CSV、二進(jìn)制)
/// </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反序列化接口(數(shù)組類型)
/// </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("\"", "'"); //將雙引號轉(zhuǎn)換為單引號,方便部分引擎解析
return newDataStr;
}
}
//轉(zhuǎn)義字符:(當(dāng)屬性值中含特殊字符時(shí),為避免解析出錯(cuò),需使用轉(zhuǎn)義字符)
//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; //是否是在一個(gè)列元素里
bool inQuotes = false; //是否需要轉(zhuǎn)義
bool isNotEnd = false; //讀取完畢未結(jié)束轉(zhuǎn)義
_columnBuilder.Remove(0, _columnBuilder.Length);
//空行也是一個(gè)空元素,一個(gè)逗號是2個(gè)空元素
if (line == "")
{
Fields.Add("");
}
// Iterate through every character in the line 遍歷行中的每個(gè)字符
for (int i = 0; i < line.Length; i++)
{
char character = line[i];
//If we are not currently inside a column 如果我們現(xiàn)在不在一列中
if (!inColum)
{
// If the current character is a double quote then the column value is contained within
//如果當(dāng)前字符是雙引號,則列值包含在內(nèi)
// double quotes, otherwise append the next character
//雙引號,否則追加下一個(gè)字符
inColum = true;
if (character == '"')
{
inQuotes = true;
continue;
}
}
// If we are in between double quotes 如果我們處在雙引號之間
if (inQuotes)
{
if ((i + 1) == line.Length) //這個(gè)字符已經(jīng)結(jié)束了整行
{
if (character == '"') //正常轉(zhuǎn)義結(jié)束,且該行已經(jīng)結(jié)束
{
inQuotes = false;
continue;
}
else //異常結(jié)束,轉(zhuǎn)義未收尾
{
isNotEnd = true;
}
}
else if (character == '"' && line[i + 1] == _csvSeparator) //結(jié)束轉(zhuǎn)義,且后面有可能還有數(shù)據(jù)
{
inQuotes = false;
inColum = false;
i++; //跳過下一個(gè)字符
}
else if (character == '"' && line[i + 1] == '"') //雙引號轉(zhuǎn)義
{
i++; //跳過下一個(gè)字符
}
else if (character == '"') //雙引號單獨(dú)出現(xiàn)(這種情況實(shí)際上已經(jīng)是格式錯(cuò)誤,為了兼容暫時(shí)不處理)
{
throw new System.Exception("格式錯(cuò)誤,錯(cuò)誤的雙引號轉(zhuǎn)義");
}
//其他情況直接跳出,后面正常添加
}
else if (character == _csvSeparator)
{
inColum = false;
}
// If we are no longer in the column clear the builder and add the columns to the list
/// 結(jié)束該元素時(shí)inColumn置為false,并且不處理當(dāng)前字符,直接進(jìn)行Add
if (!inColum)
{
Fields.Add(_trimColumns ? _columnBuilder.ToString().Trim() : _columnBuilder.ToString());
_columnBuilder.Remove(0, _columnBuilder.Length);
}
else //追加當(dāng)前列
{
_columnBuilder.Append(character);
}
}
// If we are still inside a column add a new one (標(biāo)準(zhǔn)格式一行結(jié)尾不需要逗號結(jié)尾,而上面for是遇到逗號才添加的,為了兼容最后還要添加一次)
if (inColum)
{
if (isNotEnd)
{
_columnBuilder.Append("\r\n");
}
Fields.Add(_trimColumns ? _columnBuilder.ToString().Trim() : _columnBuilder.ToString());
}
else //如果inColumn為false,說明已經(jīng)添加,因?yàn)樽詈笠粋€(gè)字符為分隔符,所以后面要加上一個(gè)空元素
{
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); //讀取所有的文本內(nèi)容
string[] lines = content.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);
//以換行回車拆分字符串,去除空格
//注:回車換行可能對某些文本不適用,這里如果我們出現(xiàn)讀取不正常,可以改用 \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);
//獲取當(dāng)前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(",");
}
//移除最后一個(gè)","
strColumn.Remove(strColumn.Length - 1, 1);
sb_Text.AppendLine(strColumn.ToString());
//依次遍歷數(shù)據(jù)列表,得到其他行屬性值文本
for (int i = 0; i < dataList.Count; i++)
{
var model = dataList[i];
strValue.Clear();
//獲取每一組數(shù)據(jù)中對應(yīng)的屬性值
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 結(jié)構(gòu)體二進(jìn)制
/// <summary>
/// 結(jié)構(gòu)體轉(zhuǎn)換為二進(jìn)制數(shù)組
/// </summary>
/// <param name="structObj">結(jié)構(gòu)體</param>
/// <returns>轉(zhuǎn)換后的二進(jìn)制數(shù)組</returns>
public static byte[] StructToBytesFunc(object structObj)
{
//得到結(jié)構(gòu)體的大小
int size = Marshal.SizeOf(structObj);
//創(chuàng)建byte數(shù)組
byte[] bytes = new byte[size];
//分配結(jié)構(gòu)體大小的內(nèi)存空間
IntPtr structPtr = Marshal.AllocHGlobal(size);
//將結(jié)構(gòu)體拷貝到分配的內(nèi)存空間
Marshal.StructureToPtr(structObj, structPtr, false);
//從內(nèi)存空間拷貝到byte數(shù)組
Marshal.Copy(structPtr, bytes, 0, size);
//釋放內(nèi)存空間
Marshal.FreeHGlobal(structPtr);
//返回byte數(shù)組
return bytes;
}
/// <summary>
/// byte數(shù)組轉(zhuǎn)結(jié)構(gòu)
/// </summary>
/// <param name="bytes">byte數(shù)組</param>
/// <param name="type">結(jié)構(gòu)類型</param>
/// <returns>轉(zhuǎn)換后的結(jié)構(gòu)</returns>
public static object BytesToStructFunc(byte[] bytes, Type type)
{
int size = Marshal.SizeOf(type);
//byte數(shù)組長度小于結(jié)構(gòu)的大小
if (size > bytes.Length)
{
//返回空
return null;
}
//分配結(jié)構(gòu)大小的內(nèi)存空間
IntPtr structPtr = Marshal.AllocHGlobal(size);
//將byte數(shù)組拷貝到分配好的內(nèi)存空間
Marshal.Copy(bytes, 0, structPtr, size);
//將內(nèi)存空間轉(zhuǎn)換為目標(biāo)結(jié)構(gòu)
object obj = Marshal.PtrToStructure(structPtr, type);
//釋放內(nèi)存空間
Marshal.FreeHGlobal(structPtr);
//返回結(jié)構(gòu)
return obj;
}
#endregion
}
public class AttrForCsvColumnLabel : Attribute
{
public string Title { get; set; }
}
文章來源:http://www.zghlxwxcb.cn/news/detail-832578.html
到了這里,關(guān)于Unity數(shù)據(jù)解析(Json、XML、CSV、二進(jìn)制)的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!