Hello everyone.

The Mixed Reality Forums here are no longer being used or maintained.

There are a few other places we would like to direct you to for support, both from Microsoft and from the community.

The first way we want to connect with you is our mixed reality developer program, which you can sign up for at https://aka.ms/IWantMR.

For technical questions, please use Stack Overflow, and tag your questions using either hololens or windows-mixed-reality.

If you want to join in discussions, please do so in the HoloDevelopers Slack, which you can join by going to https://aka.ms/holodevelopers, or in our Microsoft Tech Communities forums at https://techcommunity.microsoft.com/t5/mixed-reality/ct-p/MicrosoftMixedReality.

And always feel free to hit us up on Twitter @MxdRealityDev.
Options

Reading a large file and dealing with Unity Mono versus VS .Net

I'm having a lot of trouble with very basic tasks when trying to get the Windows RT/UWP API to work in Unity. I have about zero experience with Windows dev and I'm unclear on the difference between .NET, the Windows RT, UWP, and the hololens API. So please bear with my muddled nomenclature.

I wanted to read a large file (i.e., with buffering) to do some data visualization. So I read the basic article on reading/writing files quick start. Apparently the chosen model for UWP is to do all IO asynchronously. So I write my code in VS and am able to generate an executable. However, Unity won't let me edit the scene further because my scripts don't compile in Unity because Unity uses C# 3.0 (?) and an older version of .NET.

There appears to be no solution to this problem, so I'll just have to learn to write in this older version of C# if I want to use Unity. I can't find UWP articles though that describe something as basic as reading a file WITHOUT async. Where can I learn how to write C# code that is valid for both Unity and Windows RT/UWP? Like is there an archive somewhere of the Windows RT/UWP API for this 2009-ish version of C# used in Unity?

As a side note, it seems strangely difficult to read a file without reading it all at once in Windows RT/UWP. I had to create a StorageFolder, then get a IOFile, then get a stream, then an input stream, then a DataReader, then read from that asynchronously for a fixed size, then read the string from the DataReader, then split the lines along a newline and then manage the fact that my buffer will end in the middle of a string. The ReadLines IEnumerable from the usual System.IO would have been splendid for this task but that doesn't seem to exist in the Windows RT/UWP API.

Here's what I came up with, but of course it won't work with unity:

    //create a stream and get a data reader for it. 
    var stream = await file.OpenAsync(Windows.Storage.FileAccessMode.ReadWrite);
    var inputStream = stream.GetInputStreamAt(0);
    var dataReader = new Windows.Storage.Streams.DataReader(inputStream);

    uint bufferSize = 32; //can tune this to balance better
    while (...)
    {
        uint numBytesLoaded = await dataReader.LoadAsync(bufferSize);
        //completed read?
        if (numBytesLoaded == 0) {
            finishedFile = true;
            break;
         }
        string text =dataReader.ReadString(numBytesLoaded);
        var splitLines = text.Split(new string[] { Environment.NewLine }, StringSplitOptions.None);

        /*
         *  We're reading a fixed buffer and breaking it into lines. We need to keep empty strings where breaks were so we
         *  know when we reach the end of stream vs end of line (which may be identical). 
         */
        string partialLine = "";
        string line;
        for (int i = 0; i < splitLines.Length; i++)
        {
            //did not finish exactly on line. Keep the partial line.
            if (i == splitLines.Length && splitLines[i].Length != 0)
            {
                partialLine = splitLines[i];
                Debug.Log("Finished on incomplete line:" + splitLines[i]);
                break;
            }

            //resume from what was left over, or use current split line.
            if (i == 0) {
                line = partialLine + splitLines[i];
                Debug.Log("Re-using left over from previously incomplete read: " + partialLine + splitLines[i]);
            } else {
                line = splitLines[i];
            }
            if (line.Length == 0)
                continue;

            //FINALLY! I have a line from the file to parse
           ....

Answers

  • Options
    sptspt ✭✭
    edited August 2016

    I feel your pain. I've been dealing with the same sort of issues doing internet stuff. Unity has the odd problem that there is too much documentation and its all for old versions. I type in code from the docs of the current version and the editor says the functions are deprecated. Finding out which magic code sequence is the right one is a real chore.

  • Options

    Short Answer

    I am using FileStream class with Unity for reading / writing files. In UWP it seems you are restricted where you can read / write, so you may want to use Application.persistentDataPath or you the code may also fail with exceptions.

    Details

    Code below from snippets, provides you with outline but may not compile.

    using UnityEngine;
    using System;
    using System.IO;
    
    IEnumerable readFunc(string fname)
    {
    string sourcePathStr = 
        Path.Combine(Application.persistentDataPath, fname);
    FileStream aStream = 
        new FileStream(sourcePathStr, FileMode.Open, FileAccess.Read);
    StreamReader sr = new StreamReader(aStream);
    if (sr != null)
        {
        string resultStr= sr.ReadToEnd();
        aStream.Dispose();
        }
    }
    
  • Options

    @randyiform

    Hmm, maybe I was overthinking it. I understood from this guide to migrating to UWP that all I/O had to be asynchronous but perhaps according to your code I can just use regular FileStreams. I had a lot of compiler errors last time about methods being undefined when I tried that. I'll go back and try to see if I can get it to work with plain stream readers. It is disappointing that the hololens docs are targeted towards unity which doesn't work with the UWP I/O API relying on asynchronous methods.

    @spt Agreed!

  • Options

    After reviewing some of the code in the HololensTookit, I discovered that you can just wrap code that is incompatible with Unity's .Net version with #if !UNITY_EDITOR macros.

  • Options

    @andrew said:
    After reviewing some of the code in the HololensTookit, I discovered that you can just wrap code that is incompatible with Unity's .Net version with #if !UNITY_EDITOR macros.

    "#if WINDOWS_UWP" to be more targeted if you don't need to test/run your code anywhere other than HoloLens. If you do, you can wrap your own cross platform file I/O classes using this technique.

Sign In or Register to comment.