Utilisation des fichiers CSV dans Unity3D avec C#

Pour manipluer des fichiers CSV dans Unity, il est essentiel de comprendre les règles de formatage : une cellule contenant des virgules doit être entourée de guillemets doubles, et les guillemets internes doivent être doublés. Les lignes se terminent par des caractères de nouvelle ligne (\\r\\n). La lecture doit respecter ces conventions pour une analyse correcte.

Voici une classe C# refactorisée pour gérer la lecture et l'écriture de fichiers CSV, avec des noms de variables et une logique modifiés pour plus de clarté :


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

public class CsvManager : MonoBehaviour
{
    private static char delimiter = ',';
    private static bool enableTrim = false;

    public static string FormatCsvField(string input)
    {
        string processed = input;
        if (input.Contains(","))
        {
            if (input.Contains("\""))
                processed = processed.Replace("\"", "\"\"");
            processed = "\"" + processed + "\"";
        }
        return processed;
    }

    public static string BuildCsvLine(List<string> items)
    {
        var lineBuilder = new StringBuilder();
        for (int index = 0; index < items.Count - 1; index++)
        {
            lineBuilder.Append(FormatCsvField(items[index])).Append(delimiter);
        }
        lineBuilder.Append(FormatCsvField(items[items.Count - 1])).Append("\r\n");
        return lineBuilder.ToString();
    }

    public static List<string> ExtractLineFields(string lineContent)
    {
        var fields = new List<string>();
        var fieldBuffer = new StringBuilder();
        bool insideField = false;
        bool isQuoted = false;
        bool malformedQuote = false;

        if (string.IsNullOrEmpty(lineContent))
        {
            fields.Add("");
            return fields;
        }

        for (int pos = 0; pos < lineContent.Length; pos++)
        {
            char currentChar = lineContent[pos];

            if (!insideField)
            {
                insideField = true;
                if (currentChar == '"')
                {
                    isQuoted = true;
                    continue;
                }
            }

            if (isQuoted)
            {
                if (pos + 1 == lineContent.Length)
                {
                    if (currentChar == '"')
                    {
                        isQuoted = false;
                        continue;
                    }
                    else
                    {
                        malformedQuote = true;
                    }
                }
                else if (currentChar == '"' && lineContent[pos + 1] == delimiter)
                {
                    isQuoted = false;
                    insideField = false;
                    pos++;
                }
                else if (currentChar == '"' && lineContent[pos + 1] == '"')
                {
                    pos++;
                }
                else if (currentChar == '"')
                {
                    throw new FormatException("Échappement de guillemet invalide détecté.");
                }
            }
            else if (currentChar == delimiter)
            {
                insideField = false;
            }

            if (!insideField)
            {
                fields.Add(enableTrim ? fieldBuffer.ToString().Trim() : fieldBuffer.ToString());
                fieldBuffer.Clear();
            }
            else
            {
                fieldBuffer.Append(currentChar);
            }
        }

        if (insideField)
        {
            if (malformedQuote)
                fieldBuffer.Append("\r\n");
            fields.Add(enableTrim ? fieldBuffer.ToString().Trim() : fieldBuffer.ToString());
        }
        else
        {
            fields.Add("");
        }

        return fields;
    }

    public static List<List<string>> LoadCsvFile(string path, Encoding charset)
    {
        var dataset = new List<List<string>>();
        string fileContent = File.ReadAllText(path, charset);
        string[] lines = fileContent.Split(new[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);

        foreach (var line in lines)
        {
            dataset.Add(ExtractLineFields(line));
        }

        return dataset;
    }

    public static void SaveCsvFile(string path, Encoding charset, List<List<string>> data)
    {
        var contentBuilder = new StringBuilder();
        foreach (var row in data)
        {
            contentBuilder.Append(BuildCsvLine(row));
        }
        File.WriteAllText(path, contentBuilder.ToString(), charset);
    }

    public static void DisplayCsvData(List<List<string>> data)
    {
        foreach (var row in data)
        {
            foreach (var cell in row)
            {
                Debug.Log(cell);
            }
        }
    }
}

Pour lire un fichier CSV dans Unity, utilisez la classe précédente comme suit :


var csvData = CsvManager.LoadCsvFile(Application.streamingAssetsPath + "/MonFichier.csv", Encoding.UTF8);
Debug.Log(csvData[0][0]); // Première ligne, première colonne
Debug.Log(csvData.Count); // Nombre total de lignes

Les chemins d'accès dans Unity incluent :

  • Application.dataPath : pointe vers le dossier Assets dans l'éditeur.
  • Application.persistentDataPath : répertoire persistant pour les données utilisateur, comme le sandbox iOS/Android.
  • Applicasion.streamingAssetsPath : accès aux fichiers en streaming, compatible toutes plateformes.
  • Application.temporaryCachePath : stockage temporaire pour les données de cache.

Étiquettes: Unity CSharp csv FileIO Parsing

Publié le 22 juillet à 19h45