user9560973
user9560973

Reputation:

Unity 5.6: How to import external .txt files

Using Unity 5.6 here (I know, outdated =-(). How do I import a text file from outside the Assets folder? When I ask that, I do not mean through the Editor. It is going to be input entered by the user (my own custom modding system). I need to programmatically import the contents of the text file into a string variable.
Can anyone teach me how to do this?

Upvotes: 0

Views: 1765

Answers (2)

derHugo
derHugo

Reputation: 90852

The problem with just doing something like

 string pathToFile = @"C:\somepath\sometextfile.txt";
 string textFromFile = System.IO.File.ReadAllText(pathToFile);

is that on many OS (e.g. Android, iOS, HoloLens) applications run in a sandbox with very limited access to the OSs' file system (if not explicitly granting).

So in Unity basically that is what the Application.persitentDataPath is for. It can be accessed by both, the application and the OS (for example for changing a text file later).

To ease things up I usually would do this

    private static string DataPath
    {
        get
        {
#if UNITY_EDITOR
            return Application.streamingAssetsPath;
#else
            return Application.persistentDataPath;
#endif
        }
    }

This simply uses the folder <yourUnityProject>/Assets/StreamingAssets while you are in the Editor in order to not bload data into your PC's persistent data path while testing.

Later in a build it uses the App specific folder (depending on you OS - see link above).


In the Editor create the folder Assets/StreamingAssets and place your .txt file there.

You can read using

public static string ReadFromFile(string fileName)
{
    var filePath = Path.Combine(DataPath, fileName);

    //only needed if you choose option 1 in the next step
    var copyFile = false;

    // Check if file exists
    if (!File.Exists(filePath))
    {
        // if the file does not exist (especially later in a build) 
        // you have multiple options
        // I would decide between the following three

        // OPTION 1
        // read in the text from streaming assets instead 
        // the first time and create a new file from that content
        filePath = Path.Combine(Application.streamingAssetsPath, fileName);
        copyFile = true;
        // Note: as fallback if this also does not exist use one of the other two options


        // OPTION 2
        // Alternatively you might rather want to instead create 
        // the file with some default content and change it later
        WriteToFile(fileName, "some default content");

        // OPTION 3
        // simply throw an error an do nothing
        Debug.LogErrorFormat("Error reading {0}\nFile does not exist!", filePath);
        return null;
    }

    // Read in data from file
    using (var file = File.Open(filePath, FileMode.Open, FileAccess.Read, FileShare.Read))
    {
        using (var streamReader = new StreamReader(file, Encoding.UTF8))
        {
            //this check is only needed for option 1
            // otherwise only use the else part
            if(copyFile)
            {
                var output = streamReader.ReadToEnd();
                WriteToFile(fileName, output);
                return output;
            } 
            else
            {
                return streamReader.ReadToEnd();
            }
        }
    }
}

and write using

public static void WriteToFile(string fileName, string content)
{
    var filePath = Path.Combine(DataPath, fileName);

    // Create file or overwrite if exists
    using (var file = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.Write))
    {
        using (var writer = new StreamWriter(file, Encoding.UTF8))
        {
            writer.Write(content);
        }
    }

    Debug.LogFormat("Written to {0}", filePath);
}

You can put above code simply in a public static class e.g. somthing like

public static class File
{
    //...
}

than you can call it later from everywhere by simply using

File.ReadFromFile("MyFile.txt");

without having to reference.

Upvotes: 2

Swift
Swift

Reputation: 3410

You can read a text file with:

string pathToFile = @"C:\somepath\sometextfile.txt";
string textFromFile = System.IO.File.ReadAllText(pathToFile);

// Use the data

Upvotes: 1

Related Questions