Unity数据解析(Json、XML、CSV、二进制)

这篇具有很好参考价值的文章主要介绍了Unity数据解析(Json、XML、CSV、二进制)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

注释

常见的数据解析(Json、XML、CSV、二进制)文章来源地址https://www.toymoban.com/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>
/// 数据解析(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、 &lt;      <      小于号 
    //2、 &gt;      >      大于号
    //3、 &amp;     &      和
    //4、 &apos;    '      单引号
    //5、 &quot;    "      双引号
    //6、 &lt;=     <=     小于等于
    //7、 &gt;=     >=     大于等于


    /// <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; }
}

到了这里,关于Unity数据解析(Json、XML、CSV、二进制)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 在线解析二进制报文

    智能设备应用越来越普遍,深入到生活的各个方面,从智慧农业到智能制造,从水利灌溉到电力传输,从工业生产到智能家居。智能设备应用在各个领域,设备之间都是通过数据交换来达到信息共享和互相操作,交换的数据都遵守某个协议标准,在测试时,调试时和排查问题

    2024年02月06日
    浏览(39)
  • Unity 如何导入二进制Spine文件

    总是忘记Spine导出二进制到Unity的设置,记录一下。 TIP 此教程只满足URP渲染管线与Linear颜色空间的需求 纹理打包器也修改一下拓展名(日常操作) 修改图集扩展名 不要 勾选图集的 预乘Alpha ,勾选 溢出 修改图集扩展名 .atlas.txt 可导出以下几种文件 Default Shader 设置为 Univer

    2024年02月07日
    浏览(40)
  • Python读取二进制文件:深入解析与技术实现

    目录 一、引言 二、二进制文件的基础 1、二进制文件的组成 2、二进制文件的编码 三、Python读取二进制文件的方法 1、使用内置函数open() 2、使用numpy库 四、处理读取的二进制数据 1、解析数据 2. 转换数据类型 五、总结与展望 1、高效读取二进制文件 2、处理复杂的二进制文件

    2024年02月04日
    浏览(42)
  • 深入解析位运算算法:探索数字的二进制秘密

    位运算是计算机科学中的重要概念,用于在二进制数字层面进行各种操作。本文将深入介绍位运算的基本操作,以及它在判断、计算和处理数字中的应用,包括判断2的幂次方、位图法、位掩码和寻找缺失数字等。 位操作是通过对数字的二进制表示进行操作,实现各种功能。

    2024年02月11日
    浏览(46)
  • [unity] 音频的二进制流转化为audioclip的两种方式

    1、将返回的byte[]数组,转换成float[]数组,然后将通过 audioSource.clip.SetData()方法,将音频数据赋给audiosource,实现语音播放;但这种只有wav很有可以直接用mp3需要第三方库,我没有试过 mp3的请参考:https://blog.csdn.net/L877790502/article/details/119042479 2、将返回的btye[]数组,使用file

    2024年02月11日
    浏览(48)
  • 将数据转二进制流文件,用PostMan发送二进制流请求

    一、将byte数组转二进制流文件,并保存到本地 byte [] oneshotBytes=new byte[]{78,-29,51,-125,86,-105,56,82,-94,-115,-22,-105,0,-45,-48,-114,27,13,38,45,-24,-15,-13,46,88,-90,-66,-29,52,-23,40,-2,116,2,-115,17,36,15,-84,88,-72,22,-86,41,-90,-19,-58,19,99,-4,-63,29,51,-69,117,-120,121,3,-103,-75,44,64,-58,-34,73,-22,110,-90,92,-35,-18,-128,16,-

    2024年02月15日
    浏览(47)
  • 【FPGA仿真】Matlab生成二进制、十六进制的txt数据以及Vivado读取二进制、十六进制数据并将结果以txt格式保存

    在使用Vivado软件进行Verilog程序仿真时可能需要对模块输入仿真的数据,因此我们需要一个产生数据的方法(二进制或者十六进制的数据),Matlab软件是一个很好的工具,当然你也可以使用VS等工具。 以下分别给出了使用Matlab模拟产生二进制和十六进制数据的例子,例子仅供参

    2024年02月01日
    浏览(61)
  • 【华为OD机试真题 C++语言】101、二进制差异数 | 机试真题+思路参考+代码解析

    🍂个人博客首页: KJ.JK   🍂专栏介绍: 华为OD机试真题汇总,定期更新华为OD各个时间阶段的机试真题,每日定时更新,本专栏将使用C++语言进行更新解答,包含真题,思路分析,代码参考,欢迎大家订阅学习 🎃题目描述 对于任意两个正整数A和B,定义它们之间的差异值和

    2024年02月15日
    浏览(37)
  • C语言二进制数据和16进制字符串互转

    知识点:结构体中的“伸缩型数组成员”(C99新增) C99新增了一个特性:伸缩型数组成员(flexible array member),利用这项特性声明的结构,其最后一个数组成员具有一些特性。第1个特性是,该数组不会立即存在。第2个特性是,使用这个伸缩型数组成员可以编写合适的代码,就

    2024年02月13日
    浏览(45)
  • 使用 WebSocket 发送二进制数据:最佳实践

    WebSocket  技术提供了一种在客户端和服务器间建立持久连接的方法,使得双方可以在打开连接后随时发送数据,而不必担心建立复杂的持久连接机制。同时,使用二进制数据,如ArrayBuffer,可以更有效率地传送图像、声音等信息。本指南旨在深入探讨如何使用WebSocket传输二进

    2024年04月09日
    浏览(46)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包