Search Unity

Question Read TextAsset from StreamingAssets

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

  1. saifshk17

    saifshk17

    Joined:
    Dec 4, 2016
    Posts:
    488
    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:
    488
    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:
    488
    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