意识到识别了手柄运动方向后,需要记录下来每一帧的运动位置坐标,只有这样,才能进一步对轨迹围成的图形进行分析。那么,最方便的就是存成本地二进制文件。
于是学习了有关聊天记录的本地二进制存储的博客,只需要把其中的聊天记录的数据类换成位置坐标的数据结构就可以了。
储存为本地二进制文件的几种方式——
一、Stream::Write,Stream::WriteLine
这个方法是打开数据流就开始写字符串,可以指定长度写,也可以一行一行的写。具体参考http://blog.csdn.net/dingxiaowei2013/article/details/19084859和雨松大神的http://www.xuanyusong.com/archives/1069
这种方法最简单,一行一行的写,一行一行的读,都已String的形式写下来,可以中午可以英文。
缺点是不是二进制文件,不好做数据截断获取,比如你想把一个数据包保存下来,中间的各种数据需要你在字符串中写标记符进行切分。
二、[System.Serializable]标记,BinaryFormatter或xml写入
把自己的数据类型标记成可序列化数据二进制文件,用BinaryFormatter来进行写入读取操作。
这种方法也比较简单,数据按数据结构存放,数据不用做解析直接按数据结构使用
缺点是只能存放一个数据,每次写入读取都是一个数据,并不适合大多数情况
三、自己做数据解析,BinaryWriter写入
可以定义一个数据结构,这个结构里面的确定这个数据结构里的每个变量的数据类型,如果有字符串还需要获取字符串长度放在字符串前面
也就是一般网络传输的方式。
这种方法比较麻烦,需要自己定义数据结构和确定好每个数据结构的变量数据类型,字符串需要计算长度,但是这种方法可以适合任何场景。并且数据不需要换行只管一直写入,
而且这种方面解决上面两个方式的缺点
这个方法还有一个缺点是如果数据结构改了需要改读取和写入数据的方法。
因为想着写入本地序列化不只是我一个需求,需要可拓展性。
跟进上面这些我对类结构进行了一些安排
下面是代码和解释——
数据结构基类
using UnityEngine;
using System.Collections;
public class SerializeDataBase
{
}
聊天数据的数据结构(作为示例)
using UnityEngine;
using System.Collections;
public class ChatSerializeData : SerializeDataBase
{
public long timeStamp;
public int senderID;
public int receiverID;
//public short contentLength //这里有16位代表下面的字符串长度
public string content;
}
因为是io,所有写到一个线程里,用队列的存储,读写都在同一个线程中
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Threading;
public class SerializeClassBase<T, S> where T : SerializeDataBase where S : new()
{
public delegate void LocalDataReadDelegate(List<T> dataList);
Queue<LocalDataReadDelegate> m_onReadDoneDelegateQueue = new Queue<LocalDataReadDelegate>();
Thread m_thread;
bool m_threadStart = true;
Queue<T> m_writeThreadQueue = new Queue<T>();
Queue<string> m_readThreadQueue = new Queue<string>();
private static S m_instance;
public static S Instance
{
get
{
if (m_instance == null)
m_instance = new S();
return m_instance;
}
}
public SerializeClassBase()
{
m_thread = new Thread(ThreadAsync);
m_thread.Start();
}
protected virtual void WriteFile(T data)
{
}
protected virtual List<T> ReadFile(string arg)
{
return null;
}
public void SaveData(T data)
{
m_writeThreadQueue.Enqueue(data);
}
public void GetData(string arg,LocalDataReadDelegate del)
{
m_readThreadQueue.Enqueue(arg);
m_onReadDoneDelegateQueue.Enqueue(del);
}
void ThreadAsync()
{
while (m_threadStart)
{
while(m_readThreadQueue.Count > 0)
{
m_onReadDoneDelegateQueue.Dequeue()(ReadFile(m_readThreadQueue.Dequeue()));
}
while (m_writeThreadQueue.Count > 0)
{
WriteFile(m_writeThreadQueue.Dequeue());
}
Thread.Sleep(1000);
}
}
public void StopThread()
{
m_threadStart = false;
}
}
因为写入的时候通常不需要知道是否完成,但是读取的时候需要知道什么时候读取完成,
所有这里读取写的是通过回调的形式返回
接着继承上面的类,填入位置坐标的参数结构
protected virtual void WriteFile(T data)
{
}
protected virtual List<T> ReadFile(string arg)
{
return null;
}
以上,就完成了数据存储为本地二进制文件的基本类框架。