I'm having trouble reading a text file in Unity3D. I've created a method which returns a type float[][] and takes a streamreader as argument:
public float[][] CreateWeights(StreamReader reader){
int n = 0;
float[][] Weights = new float[50][];
while((!reader.EndOfStream)){
string text = reader.ReadLine();
if (text == null)
break;
string[] strFloats = text.Split (new char[0]);
float[] floats = new float[strFloats.Length];
for(int i = 0; i<strFloats.Length; i++){
floats[i] = float.Parse(strFloats[i]);
}
Weights[n] = floats;
n++;
}
return Weights;
}
I make use of this method in void Start() to create "weights":
float[][] WeightsIH;
float[][] WeightsHO;
void Start(){
FileInfo theSourceFile = new FileInfo(Application.dataPath + "/Resources/WeightsIH.txt");
StreamReader reader = theSourceFile.OpenText();
FileInfo theSourceFile2 = new FileInfo(Application.dataPath + "/Resources/WeightsHO.txt");
StreamReader reader2 = theSourceFile2.OpenText();
WeightsIH = CreateWeights(reader);
WeightsHO = CreateWeights(reader2);
Yhidden = new float[50][];
HiddenOutput = new float[50][];
Xoutput = new float[1];
}
And this will work fine in Unity's play mode. However, after creating an executable, the files won't be found, which I do understand. So to make it work, I understood that I need to use Resources.Load and I have:
void Start(){
TextAsset text1 = Resources.Load("WeightsIH") as TextAsset;
TextAsset text2 = Resources.Load("WeightsHO") as TextAsset;
WeightsIH = CreateWeights(text1);
WeightsHO = CreateWeights(text2);
Yhidden = new float[50][];
HiddenOutput = new float[50][];
Xoutput = new float[1];
}
Of course the argument type can't be a streamReader anymore, and I changed it to take TextAsset as argument. Here's how it changed:
public float[][] CreateWeights(TextAsset textAsset){
float[][] Weights = new float[50][];
string[] linesFromFile = textAsset.text.Split("\n"[0]);
for(int i = 0; i<linesFromFile.Length; i++){
string[] strFloats = linesFromFile[i].Split (new char[0]);
float[] floats = new float[strFloats.Length];
for(int j = 0; j<strFloats.Length; j++){
floats[j] = float.Parse(strFloats[j]);
}
Weights[i] = floats;
}
return Weights;
}
Now this won't work at all, not even in play mode. The run-time error I would get is as follows:
FormatException: Invalid format.
System.Double.Parse (System.String s, NumberStyles style, IFormatProvider provider) (
at /Users/builduser/buildslave/mono-runtime-and-classlibs/build/mcs/class/corlib/System/Double.cs:209) System.Single.Parse (System.String s) (
at /Users/builduser/buildslave/mono-runtime-and-classlibs/build/mcs/class/corlib/System/Single.cs:183) FollowShortestPath.CreateWeights (UnityEngine.TextAsset textAsset) (
at Assets/Scripts/Pathfinding/FollowShortestPath.cs:203) FollowShortestPath.Start () (
at Assets/Scripts/Pathfinding/FollowShortestPath.cs:54)
line 54 refers to:
WeightsIH = CreateWeights(text1);
and line 203 refers to:
floats[j] = float.Parse(strFloats[j]);
What am I doing wrong? How can I get the text files to be read successfully in in the executable?
The problem you have is with text file format you are loading.
Couse you have many white spaces
string[] strFloats = text.Split (new char[0]);
will result in that some strings are empty.
To fix this, remove extra withe spaces from text files or use:
for(int j = 0; j<strFloats.Length; j++){
if (string.IsNullOrEmpty (strFloats [j]))
continue;
floats[j] = float.Parse(strFloats[j]);
}