Unity 实现转策划Execl文档,并根据Xml配置文件生成代码

本工具主要还是依赖别人提供的一个解析Excel文件的工具。

下载链接:http://www.xuanyusong.com/archives/2429

工具实现的过程是将Excel表中的数据根据xml配置文件读取出来后,然后又根据xml文件写入一个自定义的文件中。游戏中就还是根据xml配置读取数据。

首先来看一下xml配置文件吧:

<?xml version="1.0" encoding="gb2312" standalone="yes" ?>
<metalib tagsetversion="1" name="" version="1">
  <table name="test">
      <column  name="id" type="int" count ="1" descript ="id"/>
      <column  name="name" type="string" count ="1" descript ="name"/>
      <column  name="sex" type="int" count ="1" descript ="sex"/>
     <column  name="age" type="int" count ="1" descript ="age"/>
    <column  name="descrip" type="string" count ="1" descript ="descrip"/>
  </table>
  <table name="test1">
    <column  name="id" type="int" count ="1" descript ="id"/>
    <column  name="name" type="string" count ="3" descript ="name"/>
    <column  name="sex" type="int" count ="1" descript ="sex"/>
    <column  name="age" type="int" count ="1" descript ="age"/>
    <column  name="descrip" type="string" count ="1" descript ="descrip"/>
  </table>
  <table name="test2">
    <column  name="id" type="int" count ="1" descript ="id"/>
    <column  name="name" type="string" count ="1" descript ="name"/>
    <column  name="sex" type="int" count ="3" descript ="sex"/>
    <column  name="age" type="int" count ="1" descript ="age"/>
    <column  name="descrip" type="string" count ="1" descript ="descrip"/>
  </table>
</metalib>

这其中每一个table就对应一个Excel表,table标签中就是表的字段。

下面就是整个工具的全部代码:

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.IO;
using Excel;
using System.Data;
using System.Xml;
using System.Threading;
using UObject = UnityEngine.Object;

public class ExeclRead : EditorWindow
{
    private static string m_TableXmlData = "GameData/Data.xml";
    private static string m_CsCodePath = "GameData/GameDataClass.cs";
    private static string m_ChangedTableDataPath = "GameData";
    private static string m_ChangedTableDataPathExtend = ".tdr";
    private static string m_GameDataParentClassName = "GameDataParent";
    private static string m_GameDataInitFunName = "SetData";

    private static string m_ApplictionDataPath = "";
    private static bool m_IsShowBar = false;
    private static float m_BarValue = 0.0f;
    private static string m_BarTitle = "";
    private static string m_BarMessage = "";

    private static bool m_IsRefreshAsset = false;
    [MenuItem("Tools/GameData/GenerateCode")]
    public static void GenerateCode()
    {
        m_ApplictionDataPath = Application.dataPath;
        new Thread(GenerateCodeTherad).Start();
    }

    [MenuItem("Tools/GameData/Execl")]
    public static void ChangeExcel()
    {
        m_ApplictionDataPath = Application.dataPath;
        UObject[] excelTables = Selection.GetFiltered(typeof(UObject), SelectionMode.DeepAssets);
        foreach (var table in excelTables)
        {
            string tableName = AssetDatabase.GetAssetPath(table);
            if (tableName.IndexOf(".xls") != -1 || tableName.IndexOf(".xlsx") != -1)
            {
                string tableCompeletPath = GetAssetPath(tableName);
                ChangeTable(tableCompeletPath);
            }
        }
    }

    [MenuItem("Tools/GameData/Test")]
    public static void GameDataTest() {
        m_ApplictionDataPath = Application.dataPath;
        UObject[] excelTables = Selection.GetFiltered(typeof(UObject), SelectionMode.DeepAssets);
        string xmlPath = m_ApplictionDataPath + "/" + m_TableXmlData;
        XmlDocument xmlDoc = new XmlDocument();
        xmlDoc.Load(xmlPath);
        XmlNodeList tableNodes = xmlDoc.GetElementsByTagName("table");
        foreach (var table in excelTables)
        {
            string tableName = AssetDatabase.GetAssetPath(table);
            if (tableName.IndexOf(".tdr") != -1)
            {
                string tableCompeletPath = GetAssetPath(tableName);
                FileStream fileStream = File.Open(tableCompeletPath, FileMode.Open, FileAccess.Read);
                XmlNode targetTable = null;
                foreach (XmlNode fildtable in tableNodes)
                {
                    if (fildtable.Attributes["name"].Value == table.name)
                    {
                        targetTable = fildtable;
                        break;
                    }
                }
                if (targetTable == null) continue;
                XmlNodeList tableFilds = targetTable.ChildNodes;
                while (fileStream.Position < fileStream.Length) {
                    foreach (XmlNode fild in tableFilds)
                    {
                        string name = fild.Attributes["name"].Value;
                        string type = fild.Attributes["type"].Value;
                        int cout = int.Parse(fild.Attributes["count"].Value);
                        for (int k = 0; k < cout; k++)
                        {
                            switch (type)
                            {
                                case "float":
                                    byte[] fvalue = new byte[4];
                                    fileStream.Read(fvalue, 0, 4);
                                    float fvalu = BitConverter.ToSingle(fvalue,0);
                                    Debug.Log(fvalu);
                                    break;
                                case "int":
                                    byte[] ivalue = new byte[4];
                                    fileStream.Read(ivalue, 0, 4);
                                    int inva = BitConverter.ToInt32(ivalue,0);
                                    Debug.Log(inva);
                                    break;
                                case "string":
                                    byte[] blength = new byte[4];
                                    fileStream.Read(blength, 0, 4);
                                    int length= BitConverter.ToInt32(blength,0);
                                    byte[] bvalue = new byte[length];
                                    fileStream.Read(bvalue, 0, bvalue.Length);
                                    string temp = Encoding.UTF8.GetString(bvalue);
                                    Debug.Log(temp);
                                    break;
                            }
                        }
                    }
                }
                fileStream.Close();
            }
        }
    }

    /// <summary>
    /// 开始创建数据表对应的Class
    /// </summary>
    static void  GenerateCodeTherad() {
        string xmlPath = m_ApplictionDataPath + "/" + m_TableXmlData;
        if (!File.Exists(xmlPath)) return;
        XmlDocument xmlDoc = new XmlDocument();
        xmlDoc.Load(xmlPath);
        XmlNodeList tableNodes = xmlDoc.GetElementsByTagName("table");
        int allCount = tableNodes.Count;
        int currentCounut = 0;
        StringBuilder allCodeContent = new StringBuilder( "using System;\r\n using System.Collections; \r\n");
        //写入父类
        allCodeContent.Append(GenerParentClassCode(m_GameDataParentClassName, m_GameDataInitFunName));
        foreach (XmlNode table in tableNodes)
        {
            string tableName = table.Attributes["name"].Value;
            ShowBar("Generate Code", "generate code  " + tableName, currentCounut / allCount);
            allCodeContent.Append(StartGenerateCode(table));
        }
        string fileName = m_ApplictionDataPath + "/" + m_CsCodePath;
        if (File.Exists(fileName))
        {
            File.Delete(fileName);
        }
        FileStream csCodeFilStream = File.Open(fileName, FileMode.CreateNew, FileAccess.ReadWrite);
        byte[] csCodeContent = Encoding.UTF8.GetBytes(allCodeContent.ToString());
        csCodeFilStream.Write(csCodeContent, 0, csCodeContent.Length);
        csCodeFilStream.Close();
        HiddenBar();
        RefreshAsset();
    }

    /// <summary>
    /// 生成数据表对应的Class的父类
    /// </summary>
    /// <param name="className"></param>
    /// <param name="dataInitFunName"></param>
    /// <returns></returns>
    static string GenerParentClassCode(string className, string dataInitFunName) {
        if (string.IsNullOrEmpty(className) || string.IsNullOrEmpty(dataInitFunName)) return "";
        CsCodeBuild parent = new CsCodeBuild(className);
        CodeFunction codeFun = new CodeFunction();
        codeFun.name = dataInitFunName;
        codeFun.parms = new Dictionary<string, string>();
        codeFun.parms.Add("data", "Hashtable");
        codeFun.isVirtual = true;
        parent.AddCodeFunction(codeFun);
        return parent.codeContent;
    }

    /// <summary>
    /// 根据数据表创建对应的Class
    /// </summary>
    /// <param name="tableNode"></param>
    /// <returns></returns>
    public static string StartGenerateCode(XmlNode tableNode) {
        if (tableNode == null) return "";
        XmlAttributeCollection attrs = tableNode.Attributes;
        string className = attrs["name"].Value;
        CsCodeBuild codeBuulder = new CsCodeBuild(className);
        codeBuulder.AddExtendClass(m_GameDataParentClassName);
        XmlNodeList fildLists = tableNode.ChildNodes;
        StringBuilder functionContent = new StringBuilder("");
        foreach (XmlNode fild in fildLists) {
            int count = int.Parse(fild.Attributes["count"].Value);
            string type = fild.Attributes["type"].Value;
            string name = fild.Attributes["name"].Value;
            CodeFild codeFild = new CodeFild();
            codeFild.name = name;
            codeFild.type = type;
            codeFild.descript = fild.Attributes["descript"].Value;
            codeFild.isArray = count > 1;
            codeFild.arrayCount = count;
            codeBuulder.AddCodeFild(codeFild);
            functionContent.Append(GenerateFunctionContent(name,type,count));
        }
        Dictionary<string, string> parms = new Dictionary<string, string>();
        parms.Add("data", "Hashtable");
        CodeFunction codeFun = new CodeFunction();
        codeFun.name = m_GameDataInitFunName;
        codeFun.content = functionContent.ToString();
        codeFun.parms = parms;
        codeFun.isOverried = true;
        codeBuulder.AddCodeFunction(codeFun);
        return codeBuulder.codeContent;
    }

    /// <summary>
    /// 生成对应的列的读取方式
    /// </summary>
    /// <param name="name"></param>
    /// <param name="type"></param>
    /// <param name="count"></param>
    /// <returns></returns>
    static string GenerateFunctionContent(string name, string type, int count) {
        StringBuilder funcContent = new StringBuilder();
        funcContent.Append("\t\t\t");
        funcContent.Append(name);
        if (count > 1)
        {
            funcContent.Append( " = data[\"" );
            funcContent.Append( name );
            funcContent.Append("\"] as ");
            funcContent.Append( type );
            funcContent.Append("[];\r\n");
        }
        else
        {
            switch (type)
            {
                case "float":
                    funcContent.Append( " = Convert.ToSingle(data[\"");
                    funcContent.Append( name );
                    funcContent.Append("\"]);\r\n");
                    break;
                case "int":
                    funcContent.Append(" = Convert.ToInt32(data[\"");
                    funcContent.Append(name);
                    funcContent.Append("\"]);\r\n");
                    break;
                default:
                    funcContent.Append(" = data[\"" );
                    funcContent.Append(  name );
                    funcContent.Append( "\"] as ");
                    funcContent.Append(type);
                    funcContent.Append(";\r\n");
                    break;
            }
        }

        return funcContent.ToString();
    }

    public static void ChangeTable( string tableCompeletPath) {
        string xmlPath = m_ApplictionDataPath + "/" + m_TableXmlData;
        if (string.IsNullOrEmpty(tableCompeletPath)) return;
        if (!File.Exists(tableCompeletPath)) return;
        FileStream stream = File.Open(tableCompeletPath, FileMode.Open,FileAccess.Read);
        IExcelDataReader excelReader = ExcelReaderFactory.CreateOpenXmlReader(stream);
        DataSet result = excelReader.AsDataSet();
        int columns = result.Tables[0].Columns.Count;
        int rows = result.Tables[0].Rows.Count;

        FileInfo fileInfo = new FileInfo(tableCompeletPath);
        string tableName = fileInfo.Name.Substring(0, fileInfo.Name.IndexOf("."));
        string fileName = fileInfo.DirectoryName+"/" + tableName + m_ChangedTableDataPathExtend;
        XmlDocument xmlDoc = new XmlDocument();
        xmlDoc.Load(xmlPath);
        XmlNodeList tableNodes = xmlDoc.GetElementsByTagName("table");
        XmlNode targetTable = null;
        foreach (XmlNode table in tableNodes) {
            if (table.Attributes["name"].Value == tableName) {
                targetTable = table;
                break;
            }
        }
        if (targetTable == null) {
            Debug.LogError("dont find table " + tableName);
            return;
        }
        if (File.Exists(fileName))
        {
            File.Delete(fileName);
        }

        FileStream gameDataStream = File.Open(fileName, FileMode.CreateNew, FileAccess.ReadWrite);
        XmlNodeList fildLists = targetTable.ChildNodes;
        for (int i = 1; i < rows; i++)
        {
            for (int j = 0; j < columns; j++)
            {
                XmlNode fild = fildLists[j];
                string type = fild.Attributes["type"].Value;
                int cout = int.Parse(fild.Attributes["count"].Value);
                for (int k = 0; k < cout; k++) {
                    byte[] tempData = null;
                    string nvalue = result.Tables[0].Rows[i][j + k].ToString();
                    switch (type)
                    {
                        case "float":
                            float fvalue = float.Parse(nvalue);
                            tempData = BitConverter.GetBytes(fvalue);
                           // Debug.Log("write: " + fvalue + " length:" + tempData.Length);
                            break;
                        case "int":
                            int ivalue = int.Parse(nvalue);
                            tempData = BitConverter.GetBytes(ivalue);
                            //Debug.Log("write: " + ivalue + " length:" + tempData.Length);
                            break;
                        case "string":
                            tempData = Encoding.UTF8.GetBytes(nvalue);
                            int length = tempData.Length;
                            byte[] lengthData = BitConverter.GetBytes(length);
                            gameDataStream.Write(lengthData, 0, lengthData.Length);
                            //Debug.Log("write: " + nvalue + " length:" + tempData.Length);
                            break;
                    }
                    if (tempData == null) continue;
                    gameDataStream.Write(tempData, 0, tempData.Length);
                }
                j += (cout - 1);
            }
        }
        gameDataStream.Close();
    }

   static  bool IsStandType(string typeName)
    {
        bool isStandType = false;
        switch (typeName) {
            case "float":
                isStandType = true;
                break;
            case "int":
                isStandType = true;
                break;
            case "string":
                isStandType = true;
                break;
        }
        return isStandType;
    }

    public static string GetAssetPath(string path) {
        if (string.IsNullOrEmpty(path)) return null;
        string compeletPath = Application.dataPath;
        compeletPath = compeletPath.Substring(0, compeletPath.IndexOf("Assets"))+path;
        return compeletPath;
    }

    public static void ShowBar(string barTitle,string barMessage,float barValue) {
        m_IsShowBar = true;
        m_BarTitle = barTitle;
        m_BarMessage = barMessage;
        m_BarValue = barValue;
    }

    public static void HiddenBar() {
        m_IsShowBar = false;
    }

    public static void RefreshAsset() {
        m_IsRefreshAsset = true;
    }

    void OnGUI()
    {
        if (m_IsShowBar) {
            EditorUtility.DisplayProgressBar(m_BarTitle,m_BarMessage, m_BarValue);
        }

        if (m_IsRefreshAsset) {
            AssetDatabase.Refresh();
            m_IsRefreshAsset = false;
        }
    }
}

public class CodeFild
{
    public string name = "";
    public string type = "";
    public bool isArray = false;
    public string descript = null;
    public int arrayCount = 0;
    public bool isStatic = false;
}

public class CodeFunction
{
    public string name = "";
    public Dictionary<string, string> parms = null;
    public string content = "";
    public string returnType = "void";
    public bool isStatic = false;
    public bool isOverried = false;
    public bool isVirtual = false;
}


public class CsCodeBuild{

    private string m_ClassName = "";
    private string m_CodeContent = "";
    private string m_SpaceNmae = "";
    private string m_ExtendClassName = "";
    public string codeContent {
        get {
            m_CodeContent = GenerCodeContent();
            return m_CodeContent;
        }
    }

    public string className {
        get {
            return m_ClassName;
        }
    }
    private List<string> m_UseSpaceName = new List<string>();
    private List<CodeFild> m_CodeFilds = new List<CodeFild>();
    private List<CodeFunction> m_CodeFunctions = new List<CodeFunction>();
  public  CsCodeBuild(string className)
    {
        if (!string.IsNullOrEmpty(className)) {
            m_ClassName = GenerateClassName(className);
        }
    }

    public static string GenerateClassName(string className) {
        if (string.IsNullOrEmpty(className)) return null;
        string tempClassName = "";
        string upClassName = className.ToUpper();
        string fistChar = upClassName.Substring(0, 1);
        tempClassName = fistChar + className.Substring(1);
        return tempClassName;
    }

    public void AddUseSpaceName(string spaceName) {
        m_UseSpaceName.Add(spaceName);
    }

    public void AddNameSpace(string spaceName) {
        m_SpaceNmae = spaceName;
    }

    public void AddExtendClass(string extendClassName) {
        m_ExtendClassName = extendClassName;
    }
    public void AddCodeFild(CodeFild codeFild) {
        if (codeFild == null) return;
        m_CodeFilds.Add(codeFild);
    }

    public void AddCodeFunction(CodeFunction codeFunction) {
        if (codeFunction == null) return;
        m_CodeFunctions.Add(codeFunction);
    }

    string GenerCodeContent() {
        StringBuilder content = new StringBuilder("");
        //写入引用命名空间
        foreach (string spaceName in m_UseSpaceName) {
            content.Append("using ");
            content.Append(spaceName);
            content.Append(";\r\n");
        }
        //写入命名空间
        if (!string.IsNullOrEmpty(m_SpaceNmae)) {
            content.Append ( "namespace ");
            content.Append( m_SpaceNmae);
            content.Append(" { \r\n");
        }
        content.Append("public class ");
        content.Append(m_ClassName);
        //写入父类
        if (!string.IsNullOrEmpty(m_ExtendClassName)) {
            content.Append(" : ");
            content.Append(m_ExtendClassName);
        }
        content.Append(" {\r\n");
        //写入属性
        foreach (var fild in m_CodeFilds) {
            content.Append(GenerateFild(fild));
        }
        //写入方法
        foreach (var function in m_CodeFunctions) {
            content.Append(GenerateFunctionCode(function));
        }

        if (!string.IsNullOrEmpty(m_SpaceNmae))
        {
            content.Append("\t\t } \r\n");
        }

        content.Append( "\t } \r\n  \r\n");
        return content.ToString();
    }
    string GenerateFild(CodeFild codeFild) {
        if (codeFild == null) return "";
        StringBuilder fildCode = new StringBuilder();
        fildCode.Append("\t\t public ");
        fildCode.Append(codeFild.type);
        fildCode.Append(" ");
        if (codeFild.isArray)
        {
            fildCode.Append("[] ");
        }
        fildCode.Append(codeFild.name);
        fildCode.Append("; ");
        if (!string.IsNullOrEmpty(codeFild.descript))
        {
            fildCode.Append("//");
            fildCode.Append(codeFild.descript);
        }
        fildCode.Append("\r\n");
        return fildCode.ToString();
    }

    string GenerateFunctionCode(CodeFunction codeFun) {
        if (codeFun == null) return "";
        StringBuilder functionCode = new StringBuilder();
        functionCode.Append("\t\t public ");
        if (codeFun.isStatic)
        {
            functionCode.Append("static ");
        }
        if (codeFun.isOverried) {
            functionCode.Append("override ");
        }
        if (codeFun.isVirtual) {
            functionCode.Append("virtual ");
        }

        functionCode.Append(codeFun.returnType);
        functionCode.Append(" ");
        functionCode.Append(codeFun.name);
        functionCode.Append("(");
        if (codeFun.parms != null)
        {
            foreach (var parm in codeFun.parms)
            {
                functionCode.Append(parm.Value );
                functionCode.Append(" ");
                functionCode.Append(parm.Key);
            }
        }
        functionCode.Append(") { \r\n");
        functionCode.Append(codeFun.content);
        functionCode.Append(" \t\t\t } \r\n");
        return functionCode.ToString();
    }
}

代码有点多。不足的地方还请各位大神指出。

其中生成cs代码的部分还不是特别的完善。

下面就是一个读取的类:

using System.Collections;
using System.Collections.Generic;
using System.Xml;
using UnityEngine;
using System.IO;
using System;
using System.Text;
using CObject = System.Object;
public class TableDataMannager  {
    private static TableDataMannager s_Instance = null;


    private static readonly string s_XmlFilePath = "/GameData/Data.xml";
    private static readonly string s_TableParentDir = "/GameData/";


    public static TableDataMannager instance {
        get {
            if (s_Instance == null) {
                s_Instance = new TableDataMannager();
            }
            return s_Instance;
        }
    }


    private Dictionary<string, CObject> readTableData = new Dictionary<string, CObject>();


    private XmlNodeList m_XmlTable = null;
    public XmlNodeList xmlTable {
        get {
            if (m_XmlTable == null) {
                string xmlPath = Application.dataPath + s_XmlFilePath;
                XmlDocument xmlDoc = new XmlDocument();
                xmlDoc.Load(xmlPath);
                m_XmlTable = xmlDoc.GetElementsByTagName("table");
            }
            return m_XmlTable;
        }
    }


    public List<T> GetTableData<T>(string tableName) where T : GameDataParent ,new(){
        CObject temptable;
        tableName = tableName.ToLower();
        if (readTableData.TryGetValue(tableName, out temptable)) {
            return temptable as List<T>;
        }
        List<T> table = new List<T>();
        string tdrFile = Application.dataPath+ s_TableParentDir + tableName + ".tdr";
        XmlNodeList tableNodes = xmlTable;
        if (tableNodes == null) { return null; }
        XmlNode targetTable = null;
        for (int i=0;i<tableNodes.Count;i++)
        {
            if (tableNodes[i].Attributes["name"].Value.ToLower() == tableName)
            {
                targetTable = tableNodes[i];
                break;
            }
        }
        if (targetTable == null) return table;
        FileStream fileStream = File.Open(tdrFile, FileMode.Open, FileAccess.Read);
        BufferedStream bufferReader = new BufferedStream(fileStream);
        XmlNodeList tableFilds = targetTable.ChildNodes;
        while (bufferReader.Position < bufferReader.Length)
        {
            T clown = new T();
            Hashtable data = new Hashtable();
            for (int i=0;i<tableFilds.Count;i++)
            {
                string name = tableFilds[i].Attributes["name"].Value;
                string type = tableFilds[i].Attributes["type"].Value;
                int cout = int.Parse(tableFilds[i].Attributes["count"].Value);
                switch (type)
                {
                    case "float":
                        if (cout > 1)
                        {
                            data[name] = ReadFloatArray(bufferReader, cout);
                        }
                        else {
                            data[name] = ReadSingleFloat(bufferReader);
                        }
                        break;
                    case "int":
                        if (cout > 1)
                        {
                            data[name] = ReadIntArray(bufferReader, cout);
                        }
                        else {
                            data[name] = ReadSingInt(bufferReader);
                        }
                        break;
                    case "string":
                        if (cout > 1)
                        {
                            data[name] = ReadStringArray(bufferReader,cout);
                        }
                        else {
                            data[name] = ReadSingString(bufferReader);
                        }
                        break;
                }
            }
            clown.SetData(data);
            table.Add(clown);
        }
        fileStream.Close();
        readTableData.Add(tableName, table );
        return table;
    }


    float ReadSingleFloat(BufferedStream bufferReader) {
        byte[] fvalue = new byte[4];
        bufferReader.Read(fvalue, 0, 4);
         return BitConverter.ToSingle(fvalue, 0);
    }


    float[] ReadFloatArray(BufferedStream bufferReader, int count) {
        float[] data = new float[count];
        for (int i = 0; i < count; i++) {
            byte[] fvalue = new byte[4];
            bufferReader.Read(fvalue, 0, 4);
            data[i]=BitConverter.ToSingle(fvalue, 0);
        }
        return data;
    }


    int ReadSingInt(BufferedStream bufferReader) {
        byte[] ivalue = new byte[4];
        bufferReader.Read(ivalue, 0, 4);
       return BitConverter.ToInt32(ivalue, 0);
    }


    int[] ReadIntArray(BufferedStream bufferReader, int count) {
        int[] data = new int[count];
        for (int i = 0; i < count; i++)
        {
            byte[] fvalue = new byte[4];
            bufferReader.Read(fvalue, 0, 4);
            data[i] = BitConverter.ToInt32(fvalue, 0);
        }
        return data;
    }


    string ReadSingString(BufferedStream bufferReader) {
        byte[] blength = new byte[4];
        bufferReader.Read(blength, 0, 4);
        int length = BitConverter.ToInt32(blength, 0);
        byte[] bvalue = new byte[length];
        bufferReader.Read(bvalue, 0, bvalue.Length);
         return Encoding.UTF8.GetString(bvalue);
    }


    string[] ReadStringArray(BufferedStream bufferReader, int count) {
        string[] data = new string[count];
        for (int i = 0; i < count; i++)
        {
            byte[] blength = new byte[4];
            bufferReader.Read(blength, 0, 4);
            int length = BitConverter.ToInt32(blength, 0);
            byte[] bvalue = new byte[length];
            bufferReader.Read(bvalue, 0, bvalue.Length);
            data[i] = Encoding.UTF8.GetString(bvalue);
        }
        return data;
    }
}

整个的读取速度还是挺快的,经测试,10多万行也就一秒左右。(对我来说还是挺满意的)。有不足的地方还请各路大神多度指教。。

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值