본문 바로가기
유니티/중급

유니티 JSON 파일 저장 및 불러오기(2)

by 노튜 2021. 1. 23.
728x90

 

1. 파일 저장 위치

앞선 글에서는 데이터를 JSON으로 변환하고, 이를 텍스트 형식의 파일로 저장하였다.

텍스트는 누구나 읽을 수 있어, 쉽게 파일을 수정할 수 있다. 또한, JSON 파일을 저장한 위치 Application.persistentDataPath는 쉽게 접근이 가능하다. 

본 글에서는 JSON을 Binary 형식으로 파일을 저장하고, 불러오는 기능을 구현한다.

 

Window에서는 이전 글에서 언급한 바와 같이 "C:\Users\사용자\AppData\LocalLow\컴퍼니네임" 에 저장되어 있다.

사용자는 본인 컴퓨터 설정 이름이며, 컴퍼니 네임은 Player 설정의 Company Name이다.

  • File Build Settings Player settings →Projectsettings → Player
  • Edit Project Setting Player

 

Android에서는 "Data/Data/App name" 에 저장되어 있다.

App 네임은 Player 설정의 Identification의 Package Name이다.

 

https://notyu.tistory.com/68

 

유니티 JSON 파일 저장 및 불러오기(1)

유니티 기초 부분에서는 유니티의 PlayerPrefs를 사용하여 데이터를 저장 및 불러오기에 대하여 다루었다. PlayerPrefs는 int, float, string 형식을 저장 및 불러오기를 할 수 있다. 간단한 데이터를 저장

notyu.tistory.com

 

 

※ Binary 형식 또한, Binary 형식에 정통하다면 수정이 가능하다. 그러나 Text 파일보다는 Binary 형식이 더 어렵다. 더 복잡하고 어려운 방식으로 데이터를 저장하고자 한다면, Binary 형식에 더하여,  C#에서 제공하는 암호화 방식을 추가적으로 구축할 것을 추천한다. 본 글에서는 다루지 않는다. (아래 링크를 참조)

 

docs.microsoft.com/ko-kr/dotnet/standard/security/encrypting-data

 

데이터 암호화

대칭 알고리즘 또는 비대칭 알고리즘을 사용 하 여 .NET에서 데이터를 암호화 하는 방법에 대해 알아봅니다.

docs.microsoft.com

 

 

2. File IO - Binary Format

 

JsonUtility를 사용하여, 변환된 JSON(string)을 BinaryFormatter를 이용해 바이너리 형태로 변환하고, 파일에 저장한다.

파일을 불러올 때에는 반대로 BinaryFormatter를 사용해 JSON으로 변환하고, JsonUtility를 사용해 Data로 변환한다.

 

BinaryFormatter를 사용하기 위해서는 아래의 위치를 지정해주어야 한다.

using System.Runtime.Serialization.Formatters.Binary;

BinaryFormatter 클래스는 Serialize()와 Deserialize() 함수를 제공한다. 매개변수로 FileStream과 object 타입을 입력한다.

여기서는 JSON(string)을 매개변수로 전달한다.

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class DataManager : MonoBehaviour
{
    public SaveLoadData MyData { get; private set; }

    private void Awake()
    {
       LoadData();
    }
    public void SaveData()
    {
        // Save 
        SaveLoadHelper.DataSave(MyData, "Data");
    }

    public void LoadData()
    {
        bool fileExist = SaveLoadHelper.FileExists("Data");
        if (fileExist)
        {
            MyData = SaveLoadHelper.DataLoad<SaveLoadData>("Data");
        }
        else
        {
            MyData = new SaveLoadData();
        }
    }
}

public class MySaveLoadData
{
    public string name;
    public int age;
    public float weight;
    // ...
}

 

 

정적 클래스를 만들어 파일을 저장하고 불러오도록 구현한다.

using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using UnityEngine;

public static class SaveLoadHelper 
{
    public static bool FileExists(string _fileName)
    {
        string path = Application.persistentDataPath + "/" + _fileName;
        return File.Exists(path);
    }

    public static void DataSave<T>(T data, string _fileName)
    {
        try
        {
            string json = JsonUtility.ToJson(data);

            if (json.Equals("{}"))
            {
                Debug.Log("" + "json null");
                return;
            }
            string path = Application.persistentDataPath + "/" + _fileName;

            FileStream fileStream = new FileStream(path, FileMode.Create);
            BinaryFormatter formatter = new BinaryFormatter();

            formatter.Serialize(fileStream, json);
            fileStream.Close();
            //    Debug.Log(json);
        }
        catch (FileNotFoundException e)
        {
            Debug.Log("The file was not found:" +e.Message);
        }
        catch (DirectoryNotFoundException e)
        {
            Debug.Log("The directory was not found: " + e.Message);
        }
        catch (IOException e)
        {
            Debug.Log("The file could not be opened:" + e.Message);
        }
    }


    public static T DataLoad<T>(string _fileName)
    {
        string path = Application.persistentDataPath + "/" + _fileName;

        try
        {
            if (File.Exists(path))
            {
                FileStream stream = new FileStream(path, FileMode.Open);
                BinaryFormatter formatter = new BinaryFormatter();

                string json = formatter.Deserialize(stream) as string;

                T data = JsonUtility.FromJson<T>(json);

                stream.Close();

                Debug.Log(json);
                return data;
            }

        }
        catch (FileNotFoundException e)
        {
            Debug.Log("The file was not found:" + e.Message);
        }
        catch (DirectoryNotFoundException e)
        {
            Debug.Log("The directory was not found: " + e.Message);
        }
        catch (IOException e)
        {
            Debug.Log("The file could not be opened:" + e.Message);
        }
        // return default(T);
        return default;
    }
}

 

728x90