BufferStorage.cs 3.83 KB
Newer Older
潘栩锋's avatar
潘栩锋 committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139
using FLY.OBJComponents.Common;
using FLY.Thick.RemoteHistory;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Threading;

namespace FLY.OBJComponents.Server
{
    /// <summary>
    /// 使用csv文件保存数据的buffer, T必须是 IFlyData
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class BufferStorage<T> : Buffer<T>
        where T : IFlyData, new()
    {
        /// <summary>
        /// 多少分钟保存一次数据
        /// </summary>
        TimeSpan SaveInterval = TimeSpan.FromMinutes(5);

        /// <summary>
        /// 5分钟时间不动作保存数据
        /// </summary>
        DispatcherTimer timer;

        /// <summary>
        /// 数据改变
        /// </summary>
        bool hasChanged = false;

        /// <summary>
        /// 保存的数据路径
        /// </summary>
        string FilePath;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="filepath">数据存储路径</param>
        /// <param name="saveInterval">数据保存周期时间 单位:分钟</param>
        /// <param name="capacity">数据总容量</param>
        public BufferStorage(string filepath, int saveInterval = 5, int capacity = 1000) : base(capacity)
        {
            FilePath = filepath;
            SaveInterval = TimeSpan.FromMinutes(saveInterval);

            Load();

            if (saveInterval > 0)
            {
                timer = new DispatcherTimer();
                timer.Interval = SaveInterval;
                timer.Tick += new EventHandler(timer_Tick);
                timer.Start();
            }
            this.BufferChanged += BufferStorage_BufferChanged;
        }

        private void BufferStorage_BufferChanged(object sender, NotifyBufferChangedEventArgs<T> e)
        {
            hasChanged = true;
        }

        /// <summary>
        /// N分钟执行一次
        /// </summary>
        void timer_Tick(object sender, EventArgs e)
        {
            if (hasChanged)
            {
                Save();
            }
        }


        void Load()
        {
            if (string.IsNullOrEmpty(FilePath))
                return;
            Reset();
            hasChanged = false;
            try
            {
                using (StreamReader sr = new StreamReader(FilePath, Encoding.GetEncoding("GB2312")))
                {
                    string header = sr.ReadLine();
                    if (string.IsNullOrEmpty(header))
                        return;

                    while (!sr.EndOfStream)
                    {
                        T t = new T();
                        if (t.TryParse(header, sr.ReadLine()))
                        {
                            Add(t);
                        }
                    }
                }
            }
            catch (Exception e)
            {

            }

        }
        void Save()
        {
            if (string.IsNullOrEmpty(FilePath))
                return;

            if (!hasChanged)
                return;

            hasChanged = false;

            if (list.Count == 0)
            {
                //删除掉文件
                File.Delete(FilePath);
                return;
            }

            //以附加的方式打开只写文件。
            //若文件不存在,则会建立该文件,
            //如果文件存在,写入的数据会被加到文件尾,即文件原先的内容会被保留。
            using (StreamWriter sw = new StreamWriter(FilePath, false, Encoding.GetEncoding("GB2312")))
            {
                sw.WriteLine(list[0].GetHeader());
                for (int i = 0; i < list.Count; i++)
                    sw.WriteLine(list[i].ToString());
                sw.Flush();
                sw.Close();
            }
        }
    }
}