Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Question Read TextAsset from StreamingAssets

Discussion in 'Scripting' started by saifshk17, Mar 16, 2023.

  1. saifshk17

    saifshk17

    Joined:
    Dec 4, 2016
    Posts:
    486
    I am reading an excel file that is located in "Resources" folder of my Unity application. I now want to load the same file from different location, i.e. StreamingAssets. Now there is no StreamingAssets.Load(), so how do I load and convert the file to TextAsset?

    Code (CSharp):
    1. using UnityEngine;
    2. using System;
    3. using System.Collections;
    4. using System.Collections.Generic;
    5. using System.Text.RegularExpressions;
    6. public class CSVReader
    7. {
    8.     static string SPLIT_RE = @",(?=(?:[^""]*""[^""]*"")*(?![^""]*""))";
    9.     static string LINE_SPLIT_RE = @"\r\n|\n\r|\n|\r";
    10.     static char[] TRIM_CHARS = { '\"' };
    11.     public static List<Dictionary<string, object>> Read(string file)
    12.     {
    13.         var list = new List<Dictionary<string, object>>();
    14.         TextAsset data = Resources.Load(file) as TextAsset;
    15.         var lines = Regex.Split(data.text, LINE_SPLIT_RE);
    16.         if (lines.Length <= 1) return list;
    17.         var header = Regex.Split(lines[0], SPLIT_RE);
    18.         for (var i = 1; i < lines.Length; i++)
    19.         {
    20.             var values = Regex.Split(lines[i], SPLIT_RE);
    21.             if (values.Length == 0 || values[0] == "") continue;
    22.             var entry = new Dictionary<string, object>();
    23.             for (var j = 0; j < header.Length && j < values.Length; j++)
    24.             {
    25.                 string value = values[j];
    26.                 value = value.TrimStart(TRIM_CHARS).TrimEnd(TRIM_CHARS).Replace("\\", "");
    27.                 object finalvalue = value;
    28.                 int n;
    29.                 float f;
    30.                 if (int.TryParse(value, out n))
    31.                 {
    32.                     finalvalue = n;
    33.                 }
    34.                 else if (float.TryParse(value, out f))
    35.                 {
    36.                     finalvalue = f;
    37.                 }
    38.                 entry[header[j]] = finalvalue;
    39.             }
    40.             list.Add(entry);
    41.         }
    42.         return list;
    43.     }
    44. }
    and my LoadExcel is as :

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class LoadExcel : MonoBehaviour
    6. {
    7.  
    8.     // Start is called before the first frame update
    9.     void Start()
    10.     {
    11.         LoadItemData();
    12.     }
    13.  
    14.     public void LoadItemData(){
    15.  
    16.         //Read csv
    17.         List<Dictionary<string, object>> data = CSVReader.Read("MyExcel");
    18.  
    19.     }
    20.  
    21. }
    I know the way to load file from StreamingAssets is this way:

    Code (CSharp):
    1. IEnumerator Start () {
    2.  
    3.         string path = Path.Combine (Application.streamingAssetsPath, "MyExcel.csv");
    4.         UnityWebRequest uwr = UnityWebRequest.Get(path);
    5.         yield return uwr.SendWebRequest();
    6.  
    7.     }
    But how do I now convert it?
     
  2. FrankvHoof

    FrankvHoof

    Joined:
    Nov 3, 2014
    Posts:
    258
    uwr.downloadHandler will have the data, either in .data (as byte[]) or in .text (as string)
     
  3. saifshk17

    saifshk17

    Joined:
    Dec 4, 2016
    Posts:
    486
    yes but how do I pass it to CSVReader.Read?
    I am trying to do it this way:
    I first change the CSVReader file as:

    Code (CSharp):
    1. public static List<Dictionary<string, object>> Read(string data)
    2.     {
    3.         var list = new List<Dictionary<string, object>>();
    4.         var lines = Regex.Split(data, LINE_SPLIT_RE);
    5.  
    6. ....
    7. ....
    8.  
    and my LoadExcel file as:
    Code (CSharp):
    1. string path = Path.Combine (Application.streamingAssetsPath, "MyExcel.csv");
    2.         UnityWebRequest uwr = UnityWebRequest.Get(path);
    3.         yield return uwr.SendWebRequest();
    4.  
    5. List<Dictionary<string, object>> data = CSVReader.Read(uwr.downloadHandler.text);
    But it is not able to read. It says "ID" not found, which is the attribute in my CSV column.
     
  4. FrankvHoof

    FrankvHoof

    Joined:
    Nov 3, 2014
    Posts:
    258
    I'm not sure what "LINE_SPLIT_RE" is, but you could try replacing that Regex.Split with String.Split(Environment.NewLine) or String.Split(";") (if it's a CSV).

    Have you tried looking at what is actually present in 'lines'?
     
  5. saifshk17

    saifshk17

    Joined:
    Dec 4, 2016
    Posts:
    486
    I wanted to give it a try with WebRequest, but instead I just did it with ReadAllText. You could also try with StreamReader I guess but I haven't implemented it that way.

    Also, if you guys could find a solution using WebRequest, please feel free to alter my LoadExcel script.

    Here is the code for LoadExcel file:

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class LoadExcel : MonoBehaviour {
    6.  
    7.     // Start is called before the first frame update
    8.     void Start () {
    9.         LoadItemData();
    10.     }
    11.  
    12.  
    13.     public void LoadItemData(){
    14.  
    15.         string filePath = System.IO.Path.Combine (Application.streamingAssetsPath, "MyExcel.csv");
    16.         string result;
    17.  
    18.         result = System.IO.File.ReadAllText (filePath);
    19.  
    20.         //Read csv
    21.         List<Dictionary<string, object>> data = CSVReader.Read (result);
    22.  
    23.     }
    24.  
    25. }
    and my CSVReader:

    Code (CSharp):
    1. using UnityEngine;
    2. using System;
    3. using System.Collections;
    4. using System.Collections.Generic;
    5. using System.Text.RegularExpressions;
    6. public class CSVReader
    7. {
    8.     static string SPLIT_RE = @",(?=(?:[^""]*""[^""]*"")*(?![^""]*""))";
    9.     static string LINE_SPLIT_RE = @"\r\n|\n\r|\n|\r";
    10.     static char[] TRIM_CHARS = { '\"' };
    11.     public static List<Dictionary<string, object>> Read(string data)
    12.     {
    13.         var list = new List<Dictionary<string, object>>();
    14.         //TextAsset data = Resources.Load(file) as TextAsset;
    15.         var lines = Regex.Split(data, LINE_SPLIT_RE);
    16.         if (lines.Length <= 1) return list;
    17.         var header = Regex.Split(lines[0], SPLIT_RE);
    18.         for (var i = 1; i < lines.Length; i++)
    19.         {
    20.             var values = Regex.Split(lines[i], SPLIT_RE);
    21.             if (values.Length == 0 || values[0] == "") continue;
    22.             var entry = new Dictionary<string, object>();
    23.             for (var j = 0; j < header.Length && j < values.Length; j++)
    24.             {
    25.                 string value = values[j];
    26.                 value = value.TrimStart(TRIM_CHARS).TrimEnd(TRIM_CHARS).Replace("\\", "");
    27.                 object finalvalue = value;
    28.                 int n;
    29.                 float f;
    30.                 if (int.TryParse(value, out n))
    31.                 {
    32.                     finalvalue = n;
    33.                 }
    34.                 else if (float.TryParse(value, out f))
    35.                 {
    36.                     finalvalue = f;
    37.                 }
    38.                 entry[header[j]] = finalvalue;
    39.             }
    40.             list.Add(entry);
    41.         }
    42.         return list;
    43.     }
    44. }
     
    Last edited: Mar 16, 2023