Skip to content

Instantly share code, notes, and snippets.

@Urethramancer
Created July 20, 2016 05:18
Show Gist options
  • Save Urethramancer/6a90f6b771855ff7c22f7aab9f98bcbc to your computer and use it in GitHub Desktop.
Save Urethramancer/6a90f6b771855ff7c22f7aab9f98bcbc to your computer and use it in GitHub Desktop.
A simple file saving class for Unity (or really any C# project if you drop the inheriting from MonoBehaviour).
// File saving.
// The data being stored should already be serialised somehow.
// Obfuscation is not in the realm of this class either.
using UnityEngine;
using System;
using System.IO;
using System.IO.Compression;
namespace NSC
{
public class Saver : MonoBehaviour
{
// Convenience function to save strings. Saves precious seconds of typing.
public static bool SaveData(string filename, string data, bool compress = true)
{
return SaveData(filename, System.Text.Encoding.ASCII.GetBytes(data), compress);
}
// Save as gzip-compatible files. Can be decompressed with command line gzip as it has a header.
// Returns true if saving went well.
public static bool SaveData(string filename, byte[] data, bool compress = true)
{
if(data == null || data.Length == 0) return false;
FileStream file = new FileStream(Application.persistentDataPath + "/" + filename, FileMode.Create);
if(file == null) return false;
if(compress)
{
GZipStream gz = new GZipStream(file, CompressionMode.Compress);
if(gz == null) return false;
gz.Write(data, 0, data.Length);
gz.Close();
} else
{
file.Write(data, 0, data.Length);
}
file.Close();
return true;
}
// Loads a file into an array, decompressing it if it's in gzip format.
public static byte[] LoadData(string filename)
{
byte[] data = null;
FileStream file = new FileStream(Application.persistentDataPath + "/" + filename, FileMode.Open);
if(file == null) return null;
GZipStream gz = null;
BinaryReader br = null;
byte[] header = new byte[3];
file.Read(header, 0, 3);
file.Position = 0;
long realsize = file.Length;
// Inspect the header for the magic numbers gzip files start with
if(header[0] == 0x1f && header[1] == 0x8b && header[2] == 8)
{
// It's gzip, so the 5th to 8th byte are the size.
// Yes, that's a 32-bit number, so file size is limited to around 2GB uncompressed.
byte[] x = new byte[4];
file.Seek(-4, SeekOrigin.End);
file.Read(x, 0, 4);
file.Seek(0, SeekOrigin.Begin);
realsize = BitConverter.ToInt32(x, 0);
gz = new GZipStream(file, CompressionMode.Decompress);
br = new BinaryReader(gz);
} else
{
// Not compressed, read it raw
br = new BinaryReader(file);
}
if(br == null) return null;
data = br.ReadBytes((int)realsize);
br.Close();
if(gz != null) gz.Close();
file.Close();
return data;
}
}
}
// Class to test that saving/compression works in Unity.
// Largely untested outside of OS X.
using UnityEngine;
using NSC;
public class SaveTesting : MonoBehaviour
{
void Start()
{
string s = "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz";
Debug.Log("Input size: " + s.Length);
Saver.SaveData("savegame", s);
byte[] s2 = Saver.LoadData("savegame");
Debug.Log("Output size: " + s2.Length);
Debug.Log("Result: " + System.Text.Encoding.ASCII.GetString(s2));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment