Unity3D中讀取CSV文件


轉自  https://www.cnblogs.com/lyh916/p/8588218.html

 

參考鏈接:

https://www.cnblogs.com/lulianqi/p/6385503.html

http://blog.csdn.net/paul342/article/details/22800137

 

說明:

1.寫入一個單元格時,如果含有逗號,則需要將整個字段用雙引號括起來;如果里面還有雙引號就替換成兩個雙引號。

2.寫入一行時,末尾要加上\r\n作為行分隔符。

3.讀取時,也要根據上面的寫入規則進行解析。

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

public class CSVTool : MonoBehaviour {
    private static char _csvSeparator = ',';
    private static bool _trimColumns = false;
    //獲取一個單元格的寫入格式
    public static string GetCSVFormat(string str)
    {
        string tempStr = str;
        if (str.Contains(","))
        {
            if (str.Contains("\""))
            {
                tempStr = str.Replace("\"", "\"\"");
            }
            tempStr = "\"" + tempStr + "\"";
        }
        return tempStr;
    }
    //獲取一行的寫入格式
    public static string GetCSVFormatLine(List<string> strList)
    {
        string tempStr = "";
        for (int i = 0; i < strList.Count - 1; i++)
        {
            string str = strList[i];
            tempStr = tempStr + GetCSVFormat(str) + ",";
        }
        tempStr = tempStr + GetCSVFormat(strList[strList.Count - 1]) + "\r\n";
        return tempStr;
    }
    //解析一行
    public 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;
    }
    //讀取文件
    public static List<List<string>> Read(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);
        for (int i = 0; i < lines.Length; i++)
        {
            List<string> line = ParseLine(lines[i]);
            result.Add(line);
        }
        return result;
    }
    //寫入文件
    public static void Write(string filePath, Encoding encoding, List<List<string>> result)
    {
        StringBuilder builder = new StringBuilder();
        for (int i = 0; i < result.Count; i++)
        {
            List<string> line = result[i];
            builder.Append(GetCSVFormatLine(line));
        }
        File.WriteAllText(filePath, builder.ToString(), encoding);
    }
    //打印
    public static void Debug(List<List<string>> result)
    {
        for (int i = 0; i < result.Count; i++)
        {
            List<string> line = result[i];
            for (int j = 0; j < line.Count; j++)
            {
                UnityEngine.Debug.LogWarning(line[j]);
            }
        }
    }
}

 

讀取csv的數據

List<List<string>> lists;
lists = CSVTool.Read(Application.streamingAssetsPath + "/TypeKeys.csv", Encoding.Default);
        //      行       列
        Debug.Log(lists[0][0]);
        //Debug.Log(lists[0][1]);
        Debug.Log(lists[1][0]);
        Debug.Log(lists.Count);

 

 

另外

關於路徑有4個類型:

Application.dataPath:該路徑指向我們Unity編輯器的Asset文件夾

Application.persistentDataPath:該路徑指向iOS和Android的沙盒路徑

Application.streamingAssetsPath:streamingAsset文件夾路徑,在任何平台都可以通過這個路徑讀取到文件夾里的內容

Application.temporaryCachePath:臨時數據文件路徑

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM