您的位置:首页 > 移动开发 > Unity3D

Unity3D 异步读取CSV文件

2016-01-12 19:19 447 查看


原创文章如需转载请注明:转载自 脱莫柔Unity3D学习之旅 Unity3D引擎技术交流QQ群:【119706192】本文链接地址: Unity3D
异步读取CSV文件

误打误撞在VR圈混迹多年,终于下决心要回来做MMOARPG手游了。

很久没有这么“充实”过了,项目进度又到了读表阶段了。

看到前些年使用的CSV读取工具类还有优化空间,所以修改后发出来跟大家交流交流,还望各路大神多加指点。

注释都在代码里,so,废话不多说直接上代码:

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System;
using System.Text;

/// <summary>
/// 读取CSV工具类
/// (需求:UTF-8格式)
/// </summary>
public class LoadCSVData : MonoBehaviour
{
public delegate void  toDirectoryCallBack(Dictionary<string, List<string>> csvdata);

/// <summary>
/// 异步开始读取CSV文档
/// </summary>
/// <param name="Filename">StreamingAssets目录内的文件名</param>
/// <param name="LoadCBK">读取完成后的回调事件</param>
/// <returns></returns>
public IEnumerator LoadCSV_toDirectory(string Filename,toDirectoryCallBack LoadCBK)
{
string CSVText = null;
yield return StartCoroutine(LoadWWW(GetFilepath(Filename), (www) => { CSVText = www; }));
Dictionary<string, List<string>> CSVData = getDirectory(readcsv(CSVText.ToString()));
LoadCBK(CSVData);
}

/// <summary>
/// 获取完整的文件路径
/// </summary>
/// <param name="Filename"></param>
/// <returns></returns>
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";
}
}
/// <summary>
/// 读取文件
/// </summary>
/// <param name="filepath">文件路径</param>
/// <param name="loadCBK">读取完成回调</param>
/// <returns></returns>
IEnumerator LoadWWW(string filepath, Action<string> 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<List<string>> readcsv(string strin)
{
return readcsv(strin, Encoding.UTF8);
}

public static List<List<string>> readcsv(string strin, Encoding encoding)
{
List<List<string>> ret = new List<List<string>>();

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<string> s = split(lines[i], encoding);
ret.Add(s);
}
return ret;
}

static List<string> split(string line, Encoding encoding)
{
byte[] b = encoding.GetBytes(line);
List<string> bls = new List<string>();
int end = b.Length - 1;

List<byte> bl = new List<byte>();
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<byte> 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
== '"')
{
if (n < bl.Count - 1 && bl[n + 1] == '"')
{
bl.RemoveAt(n + 1);
n++;
}
else
bl.RemoveAt(n);
}
else
n++;
}

return encoding.GetString(bl.ToArray());
}

/// <summary>
/// 转换成Dictionary类型
/// </summary>
/// <param name="listin"></param>
/// <returns></returns>
public static Dictionary<string, List<string>> getDirectory(List<List<string>> listin)
{
Dictionary<string, List<string>> dir = new Dictionary<string, List<string>>();
for (int i = 0; i < listin.Count; i++)
{
if (string.IsNullOrEmpty(listin[i][0]))
continue;
dir[listin[i][0]] = listin[i];
}
return dir;
}

/// <summary>
/// 打印 Csv 转换的二维数组
/// </summary>
/// <param name="grid"></param>
public static void DebugOutputGrid(string _titleName, Dictionary<string, List<string>> 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());
}

/// <summary>
/// 读取CSV格式的文档
/// </summary>
/// <returns></returns>
IEnumerator LoadCSVData_debug()
{
DateTime startTime = DateTime.Now;

Debug.Log("开始读取数据");
LoadCSVData loadcsv = gameObject.AddComponent<LoadCSVData>();

Dictionary<string, List<string>> 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);
}
}


嗯,就是这样,我忙去了~~
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  异步读取SCV