예제 #1
0
        public static IEnumerable <HistoryData> LoadFromDatabase(DateTime start, DateTime end, short?ID = null)
        {
            using (var dataReader = DataHelper.Instance.ExecuteProcedureReader("READHDATA",
                                                                               DataHelper.CreateParam("@STARTTIME", SqlDbType.DateTime, start),
                                                                               DataHelper.CreateParam("@ENDTIME", SqlDbType.DateTime, end),
                                                                               DataHelper.CreateParam("@ID", SqlDbType.Int, (object)ID ?? DBNull.Value)))
            {
                if (dataReader == null)
                {
                    yield break;
                }
                HistoryData data   = HistoryData.Empty;
                int         itime  = ID.HasValue ? 0 : 1;
                int         ivalue = ID.HasValue ? 1 : 2;
                int         itype  = ID.HasValue ? 2 : 3;
                while (dataReader.Read())
                {
                    data.ID        = ID.HasValue ? ID.Value : dataReader.GetInt16(0);
                    data.TimeStamp = dataReader.GetDateTime(itime);
                    switch ((DataType)dataReader.GetByte(itype))
                    {
                    case DataType.BOOL:
                        data.Value.Boolean = dataReader.GetFloat(ivalue) > 0 ? true : false;
                        break;

                    case DataType.BYTE:
                        data.Value.Byte = Convert.ToByte(dataReader.GetFloat(ivalue));
                        break;

                    case DataType.WORD:
                    case DataType.SHORT:
                        data.Value.Int16 = Convert.ToInt16(dataReader.GetFloat(ivalue));
                        break;

                    case DataType.INT:
                        data.Value.Int32 = Convert.ToInt32(dataReader.GetFloat(ivalue));
                        break;

                    case DataType.FLOAT:
                        data.Value.Single = dataReader.GetFloat(ivalue);
                        break;
                    }
                    yield return(data);
                }
            }
            yield break;
        }
예제 #2
0
        public static int WriteToFile(DateTime date)//每天凌晨写入昨天的数据到文件,可以考虑用服务或计划任务;数据库只保留当天的记录;调度程序负责删除过期记录;历史数据应支持合并
        {
            int    year = date.Year; int month = date.Month; int day = date.Day;
            string path = string.Concat(m_Path, "\\", year.ToString(), "-", month.ToString(), ".bin");

            if (CreateFile(year, month))//如该月文件不存在,则创建;否则写入
            {
                using (FileStream stream = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.Read))
                {
                    stream.Seek(day * 8, SeekOrigin.Begin); //先读入索引区,定位到该日期的指针
                    byte[] bits = new byte[8];
                    stream.Read(bits, 0, 8);                //如果该位置指针为>0的正数,说明该区域已有数据
                    if (BitConverter.ToInt64(bits, 0) > 0)
                    {
                        return(-1);
                    }
                }
                using (var dataReader = DataHelper.Instance.ExecuteProcedureReader("WRITEHDATA", DataHelper.CreateParam("@DATE", SqlDbType.DateTime, date)))
                {
                    if (dataReader == null)
                    {
                        return(-10);
                    }
                    else
                    {
                        dataReader.Read();
                        int cont = dataReader.GetInt32(0);//读入标签数量
                        if (cont == 0)
                        {
                            return(-2);
                        }
                        string path2 = path + ".temp";
                        try
                        {
                            File.Copy(path, path2, true);//先把原文件全部复制到临时文件
                            //Stopwatch sw = Stopwatch.StartNew();
                            using (FileStream stream = File.Open(path2, FileMode.Open))
                            {
                                //w.Seek(8 + day * 8, SeekOrigin.Begin);
                                //w.Seek(0x100, SeekOrigin.Begin);
                                long start = stream.Seek(0, SeekOrigin.End);//定位到文件末尾
                                long end   = 0;
                                using (BinaryWriter w = new BinaryWriter(stream))
                                {
                                    w.Write(new SqlDateTime(date).DayTicks); //写入日期
                                    w.Write(cont);                           ///写入标签数量
                                    int count = dataReader.GetInt32(1);
                                    w.Write(count);
                                    HDataFormat[] list = new HDataFormat[count];
                                    if (dataReader.NextResult())
                                    {
                                        int p = 0;
                                        int x = 0;
                                        while (dataReader.Read())                //写入标签元数据
                                        {
                                            short id   = dataReader.GetInt16(0); //ID号
                                            byte  type = dataReader.GetByte(1);  //数据类型
                                            int   cn   = dataReader.GetInt32(2); //标签个数
                                            //list[x].ID = id;
                                            list[x].Type  = (DataType)type;
                                            list[x].Count = cn;
                                            //list[x].Offset = p;
                                            w.Write(id);
                                            w.Write(type);
                                            w.Write(cn);
                                            w.Write(p);
                                            p += cn * dataLen[type];
                                            x++;
                                        }
                                        if (dataReader.NextResult())
                                        {
                                            for (int i = 0; i < list.Length; i++)
                                            {
                                                int len = list[i].Count;
                                                for (int j = 0; j < len; j++)
                                                {
                                                    if (dataReader.Read())
                                                    {
                                                        w.Write(dataReader.GetTimeTick(0));
                                                        switch (list[i].Type)
                                                        {
                                                        case DataType.BOOL:
                                                            w.Write(dataReader.GetFloat(1) > 0);
                                                            break;

                                                        case DataType.BYTE:
                                                            w.Write((byte)dataReader.GetFloat(1));
                                                            break;

                                                        case DataType.WORD:
                                                        case DataType.SHORT:
                                                            w.Write((short)dataReader.GetFloat(1));
                                                            break;

                                                        case DataType.INT:
                                                            w.Write((int)dataReader.GetFloat(1));
                                                            break;

                                                        case DataType.FLOAT:
                                                            w.Write(dataReader.GetFloat(1));
                                                            break;
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                    end = stream.Position;                   //文件的结尾,总长度
                                    w.Seek((day - 1) * 8, SeekOrigin.Begin); //定位到索引区
                                    w.Write(start);                          //写入当日指针
                                    w.Write(end);                            //写入下一日指针
                                    //w.Close();
                                }
                            }
                            File.Copy(path2, path, true);
                        }
                        catch (Exception err)
                        {
                            DataHelper.AddErrorLog(err);
                            return(-3);
                        }
                        finally
                        {
                            if (File.Exists(path2))
                            {
                                File.Delete(path2);
                            }
                        }
                        //dataReader.Close();
                        return(0);

                        /*写入失败,则将备份文件还原;数据库不做删除动作,保留记录,次日服务检查数据文件是否存在,不存在则合并写入
                         * 可在服务内建XML文件保存失败记录的日期列表,以便还原;用File.Mov;定时间隔、开始时间也可XML定义。
                         * 先备份二进制归档库,再加载数据库数据,写入文件;如成功,删除数据库当日记录并删除备份文件
                         * sw.Stop();
                         * if (sw.ElapsedTicks > 0) { }
                         */
                    }
                }
            }
            return(-10);
        }