Reading file repeatedly

Hey,

I do want to read some files (~20) repeatedly ( not every frame, but maybe every half second). I wonder how I do this at best performance.

My first try was:

which resulted in spikes in fps every half second. I think it went from 30fps (vsync) to 15fps. This can’t be a good way, because it always opens and closes the file.
I wrote a function, which creates a FileStream and passes that to a StreamReader. If a stream already was created, it uses that. Using the Seek method of the FileStream I can always rewind to the begining:

private Dictionary<string, StreamReader> dR = new Dictionary<string, StreamReader>();
private Dictionary<string, FileStream> dS = new Dictionary<string, FileStream>();

private string readFile(string fileName)
    {
        StreamReader sr = null;
        dR.TryGetValue(fileName, out sr);

        if (sr == null)
        {
            FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read);
            sr = new StreamReader(fs);
            dR.Add(fileName, sr);
            dS.Add(fileName, fs);
        }

        dS[fileName].Seek(0, SeekOrigin.Begin);

        string fileString = sr.ReadLine();
        return fileString;
    }

Is this the best I can do?

It works better, but I still get spikes ( not as worse as before). I use a Coroutine which has a WaitForSeconds(.5f) in a while(true) loop. Also I added a yield return every ~5 files i read.

Background: I do want to monitor some sensor data on android. For example the batteryTemperature is stored in a file “/sys/class/power_supply/battery/temp”. I do want to read this information in a given interval and log it into a file. I do this with File.AppendAllText(filePath, string);. Using all the data i then can make a nice graph

. But I do not want that my Performance-Logger really impacts the measurements.

I think the easiest way to avoid the spike in this case would be to use a different thread. You can use ThreadPool.QueueUserWorkItem: ThreadPool.QueueUserWorkItem Method (System.Threading) | Microsoft Learn

In Unity, new threads can not call most Unity-specific functions but it looks like your readFile method is fine. The file reading would be done on the new thread, while the normal Update() method would just keep checking to see if the thread is done and then get the string value.

1 Like