原创文章如需转载请注明:转载自 脱莫柔Unity3D学习之旅 Unity3D引擎技术交流QQ群:【119706192】本文链接地址: Unity3D 异步读取CSV文件 |
误打误撞在VR圈混迹多年,终于下决心要回来做MMOARPG手游了。
很久没有这么“充实”过了,项目进度又到了读表阶段了。
看到前些年使用的CSV读取工具类还有优化空间,所以修改后发出来跟大家交流交流,还望各路大神多加指点。
注释都在代码里,so,废话不多说直接上代码:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System;
using System.Text;
///
/// 读取CSV工具类
/// (需求:UTF-8格式)
///
public class LoadCSVData : MonoBehaviour
{
public delegate void toDirectoryCallBack(Dictionary> csvdata);
///
/// 异步开始读取CSV文档
///
/// StreamingAssets目录内的文件名
/// 读取完成后的回调事件
///
public IEnumerator LoadCSV_toDirectory(string Filename,toDirectoryCallBack LoadCBK)
{
string CSVText = null;
yield return StartCoroutine(LoadWWW(GetFilepath(Filename), (www) => { CSVText = www; }));
Dictionary> CSVData = getDirectory(readcsv(CSVText.ToString()));
LoadCBK(CSVData);
}
///
/// 获取完整的文件路径
///
///
///
string GetFilepath(string Filename)
{
switch (Application.platform)
{
case RuntimePlatform.Android:
return "jar:file://" + Application.dataPath + "!/assets/" + Filename + ".csv";
case RuntimePlatform.IPhonePlayer:
return Application.dataPath + "/Raw/" + Filename + ".csv";
default:
return "file://" + Application.dataPath + "/StreamingAssets/" + Filename + ".csv";
}
}
///
/// 读取文件
///
/// 文件路径
/// 读取完成回调
///
IEnumerator LoadWWW(string filepath, Action loadCBK)
{
WWW www = new WWW(filepath);
yield return www;
string CSVText;
if (!string.IsNullOrEmpty(www.error))
{
CSVText = www.error;
}
else
{
CSVText = www.text;
}
loadCBK(CSVText);
}
public static List> readcsv(string strin)
{
return readcsv(strin, Encoding.UTF8);
}
public static List> readcsv(string strin, Encoding encoding)
{
List> ret = new List>();
strin = strin.Replace("\r", "");
string[] lines = strin.Split('\n');
if (lines.Length > 0)
{
byte[] byt = encoding.GetBytes(lines[0]);
if (byt.Length >= 3 &&
byt[0] == 0xEF &&
byt[1] == 0xBB &&
byt[2] == 0xBF)
{
lines[0] = encoding.GetString(byt, 3, byt.Length - 3);
}
}
for (int i = 0; i < lines.Length; i++)
{
if (string.IsNullOrEmpty(lines[i]) ||
lines[i].StartsWith("#"))
continue;
List s = split(lines[i], encoding);
ret.Add(s);
}
return ret;
}
static List split(string line, Encoding encoding)
{
byte[] b = encoding.GetBytes(line);
List bls = new List();
int end = b.Length - 1;
List bl = new List();
bool inQuote = false;
for (int i = 0; i < b.Length; i++)
{
switch ((char)b[i])
{
case ',':
if (inQuote)
bl.Add(b[i]);
else
{
bls.Add(makefield(ref bl, encoding));
bl.Clear();
}
break;
case '"':
inQuote = !inQuote;
bl.Add((byte)'"');
break;
case '\\':
if (i < end)
{
switch ((char)b[i + 1])
{
case 'n':
bl.Add((byte)'\n');
i++;
break;
case 't':
bl.Add((byte)'\t');
i++;
break;
case 'r':
i++;
break;
default:
bl.Add((byte)'\\');
break;
}
}
else
bl.Add((byte)'\\');
break;
default:
bl.Add(b[i]);
break;
}
}
bls.Add(makefield(ref bl, encoding));
bl.Clear();
return bls;
}
static string makefield(ref List bl, Encoding encoding)
{
if (bl.Count > 1 && bl[0] == '"' && bl[bl.Count - 1] == '"')
{
bl.RemoveAt(0);
bl.RemoveAt(bl.Count - 1);
}
int n = 0;
while (true)
{
if (n >= bl.Count)
break;
if (bl[n] == '"')
{
if (n < bl.Count - 1 && bl[n + 1] == '"')
{
bl.RemoveAt(n + 1);
n++;
}
else
bl.RemoveAt(n);
}
else
n++;
}
return encoding.GetString(bl.ToArray());
}
///
/// 转换成Dictionary类型
///
///
///
public static Dictionary> getDirectory(List> listin)
{
Dictionary> dir = new Dictionary>();
for (int i = 0; i < listin.Count; i++)
{
if (string.IsNullOrEmpty(listin[i][0]))
continue;
dir[listin[i][0]] = listin[i];
}
return dir;
}
///
/// 打印 Csv 转换的二维数组
///
///
public static void DebugOutputGrid(string _titleName, Dictionary> grid)
{
StringBuilder textOutput = new StringBuilder();
textOutput.Append(_titleName);
textOutput.Append("\n");
foreach (var line in grid)
{
for (int i = 0; i < line.Value.Count; i++)
{
string row = line.Value[i];
textOutput.Append(row);
if (i < line.Value.Count - 1)
textOutput.Append("|");
}
textOutput.Append("\n");
}
Debug.Log(textOutput);
}
}
using UnityEngine;
using System.Collections;
using System;
using System.Collections.Generic;
public class LoadCSVDara_debug : MonoBehaviour {
// Use this for initialization
void Start ()
{
StartCoroutine(loading());
}
IEnumerator loading()
{
yield return StartCoroutine(LoadCSVData_debug());
}
///
/// 读取CSV格式的文档
///
///
IEnumerator LoadCSVData_debug()
{
DateTime startTime = DateTime.Now;
Debug.Log("开始读取数据");
LoadCSVData loadcsv = gameObject.AddComponent();
Dictionary> data = null;
//读取技能表
yield return StartCoroutine(loadcsv.LoadCSV_toDirectory("SKILL", (csvdata) => { data = csvdata; }));
Debug.Log("读取技能表花费:" + (DateTime.Now - startTime).TotalMilliseconds + "ms");
//SkillInfo.loadSkillDatas(data);
LoadCSVData.DebugOutputGrid("技能表", data);
}
}