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.

Basic File IO with HoloLens

Hey guys!

I am looking for an easy way to read and write unformatted text from and into files.

The easiest way I could imagine would be a .txt file, accessed by a filestream.

This is the code, I have just written yet:

using (FileStream fileStream = new FileStream("test.txt", FileMode.Create, FileAccess.ReadWrite))
{
inputArray = Encoding.ASCII.GetBytes(IOString);
fileStream.Write(inputArray, 0, 9999);
IOString = "Read failed";
outputArray = Encoding.ASCII.GetBytes(IOString);
fileStream.Read(outputArray, 0, 9999);
IOString = Encoding.ASCII.GetString(outputArray);
}

However I get a System.UnauthorizedAccessException, when testing it.

I tried to fix this, using FileIOPermission:

using System.Security.Permissions;

private FileIOPermission fileIOPermission;

    fileIOPermission = new FileIOPermission(FileIOPermissionAccess.AllAccess, "test.txt");
    using (FileStream fileStream = new FileStream("test.txt", FileMode.Create, FileAccess.ReadWrite))
    {
        inputArray = Encoding.ASCII.GetBytes(IOString);
        fileStream.Write(inputArray, 0, 9999);
        IOString = "Read failed";
        outputArray = Encoding.ASCII.GetBytes(IOString);
        fileStream.Read(outputArray, 0, 9999);
        IOString = Encoding.ASCII.GetString(outputArray);
    }

Unfortunately, this gets me following errors in the Unity Compiler:

error CS0234: The type or namespace name 'Permissions' does not exist in the namespace 'System.Security' (are you missing an assembly reference?)#

error CS0246: The type or namespace name 'FileIOPermission' could not be found (are you missing a using directive or an assembly reference?)

Thank you in advance,

jschnettker

Best Answer

  • stepan_stulovstepan_stulov ✭✭✭
    Accepted Answer

    @jschnettker

    You are trying to load a TextAsset from something that is not a TextAsset. You have to create an instance of TextAsset (an *.asset file) via Editor script like I described earlier. Again, just like I described, you tried combining two different systems: Unity's TextAssets and manually creating (completely unrelated to them) *.txt files.

    Hope this helps.

    Building the future of holographic navigation. We're hiring.

Answers

  • Where you are trying to load the file from?

    You will need to set permissions for that folder to allow you to access it. In Unity you can find these under PlayerSettings and then Publish Settings and Capabilities.

    Taqtile

  • Hi mark_grossnickle,

    thanks for your reply! I changed the path to "C:\test.txt", and created a test.txt file in my C: PC harddrive. It does not find it, so I guess it should be on the HoloLens. Anyway, the FileStream should create the file, when it is missing:

    https://msdn.microsoft.com/en-us/library/47ek66wy(v=vs.110).aspx

    But I see that you need the FileIOPermissionAccess, to use this.

    You've stated, that there is a possibility, to enable this in the player settings capabilities. However, I can not find any suitable checkbox for that.

    Thank you anyway,

  • If anyone has another idea, how to enable file IO with HoloLens, I would be happy to read about it.

  • Hey, @jschnettker

    If you're using Unity, you can use the UnityEngine.VR.Windows.File class.

    Building the future of holographic navigation. We're hiring.

  • mark_grossnicklemark_grossnickle ✭✭✭
    edited September 2017

    The file needs to be on your Hololens. You could place it in your Resources folder within Unity and that should be accessible for the app. I assumed the file needed to be external from the app though. Are you planning on having the file exist within the app or does it need to be loaded in an external folder?

    Taqtile

  • Hey Guys!

    Thanks for replying!

    @stepan_stulov Thanks for the suggestion! It works great in unity playmode.

    @everybody What would be an accessible path on the HoloLens? I tried the rootpath

  • "test.txt" and the relative path "Assets\Ressources\InfoData\test.txt". Of course I created the folder and it worked out in playmode. But when try it on the HoloLens, I get the following in my output:

    File.WriteAllBytes - failed to open test.txt for writing
    (Filename: C:/buildslave/unity/build/artifacts/generated/Metro/runtime/WindowsFileBindings.gen.cpp Line: 61)

    File.ReadAllBytes - failed to open test.txt for reading
    (Filename: C:/buildslave/unity/build/artifacts/generated/Metro/runtime/WindowsFileBindings.gen.cpp Line: 34)

    I have no idea how to fix this.

    Thanks in advance,

    jschnettker

  • stepan_stulovstepan_stulov ✭✭✭
    edited September 2017

    Hey, @jschnettker

    When dealing with Unity you usually don't "re-invent the wheel" with your app's persistent folders and do file IO under Application.persistentDataPath, which is set for you automatically depending on the platform (also be aware of play mode vs. actual build). Print it out on each platform to see where it actually is. Destinations vary dramatically but do conform to each platform's conventions. You will want to use Path.Combine() method and attach file names or subfolders to get the final destination. Path.Combine() also takes care of platofmr-specific things like slash vs baclslash. Application.persistentDataPath is "the clean" way when doing traditional file IO. And this is what I recommend for your case.

    string myFileFullPath = Path.Combine(Application.persistentDataPath, "MyFile.txt");

    Resources folder is for something completely different and, if I may, is irrelevant to your case. Resources system is for Unity to force compiling assets into your build despite the fact that they're not directly referenced in your build-included scenes. You later will access those resources by calling Resources.Load() method. Resources are usually Unity-recognizable assets, such as textures, prefabs, animations etc. Amongst them there is also TextAsset. Resources' philosophy is to be authored in Editor, forced to be compiled-in and later loaded and unloaded on demand at runtime. You don't edit Resources at runtime! Well, I guess you technically can but that's very hack-y.

    There are also PlayerPrefs for storing small data by string keys for some small stuff.

    There are plenty of data storage and delivery paradigms in Unity: PlayerPrefs, AssetBundles, ScriptableObjects, Resources, traditional file IO. I would suggest using the one that best suits your case but then play by the rules of that paradigm. I recommend not mixing them up. Using Resources with traditional file IO (which seems to be recommended here) is one such case of mixing up.

    Hope this helps.

    Building the future of holographic navigation. We're hiring.

  • edited September 2017

    Hi, @stepan_stulov!

    I am not 100% sure, but according to your explanation of the resources system, this could be pretty much what I want.

    To be exact: I want to have a folder on my pc in the unity project, to be fed with some .txt files. Next step is loading up the app. During runtime, I want to access a certain one of these .txt files, based on an environmental event. Then I want to display this text on a unity text.

    If you know an easier to do so, I would be happy to read about it.

    Thanks so much!

    Edit: I read more about resources, and you were right. But how could I store
    a .txt file in my unity project directory, that is accessible to the HoloLens
    app?

  • stepan_stulovstepan_stulov ✭✭✭
    edited September 2017

    So, @jschnettker, if you only need to deliver the text assets to runtime and don't need to edit them at runtime, then TextAsset is the way to go as it's in the Unity philosophy.

    There are two things to this:

    First create a TextAsset you'd need a little bit of Editor scripting, because Untiy doesn't have a direct way to do so. TextAsset is a little bit of a dark horse. It's very easy to do, see the link below. This will create a separate asset file in your project folder which you can populate with text via the inspector.
    http://answers.unity3d.com/questions/309351/create-a-textasset-from-a-string.html

    Now you have two choices of how to deliver that text assets:
    1. You simply declare a serializable field in some of your scripts that has type TextAsset. You will simply be able to drag'n'drop that text asset file onto that field in the inspector. Then simply use the field's text or bytes fields. Boom done. This choice is for when you have fewer smaller text assets and it's ok to unwrap them all during runtime.
    2. You can put your text assets under Resources folder. Make sure that you then don't directly reference it like in the option above because it kind of defeats the purpose of resources. Now simply load the asset with Resources.Load(). From then one it's the same as the the first option. This option is for when having all the text assets unwrapped in memory at the same time leaves too big of a memory imprint.

    Voila.

    PS: You text asset won't be a *.txt, it will be *.asset I believe. If you force text serialization in your Unity project that will be a YAML file, if I'm not mistaken.

    Building the future of holographic navigation. We're hiring.

  • Hi @stepan_stulov !

    Many thanks! The first option works fine, but the second does not yet.
    I created the .txt files simply via NotePad.
    But with this code:

        infoInputText = Resources.Load(fileName + ".txt") as TextAsset;
        IOString = infoInputText.text;
        infoDisplayText.text = "ID: " + IOString;
    

    I always get a System.NullReferenceException: Object reference not set to an instance of an object.
    Do you have an idea to fix this?
    jschnettker

  • stepan_stulovstepan_stulov ✭✭✭
    Accepted Answer

    @jschnettker

    You are trying to load a TextAsset from something that is not a TextAsset. You have to create an instance of TextAsset (an *.asset file) via Editor script like I described earlier. Again, just like I described, you tried combining two different systems: Unity's TextAssets and manually creating (completely unrelated to them) *.txt files.

    Hope this helps.

    Building the future of holographic navigation. We're hiring.

Sign In or Register to comment.