我的软件是对下位机进行实时监控 需要不断的往下位机发命令 然后下位机返回当时的一写参数 过去是写在数据库里的 但是数据量很大 就改成往DAT 文件里写数据了 也就是说后台由DAT文件 代替了 数据库 但是在查看数据的时候 发现里面的数据中许多参数为0 这在现实情况中是不可能的 所以我怀疑是在写文件的时候出现的异常 但是又站不住脚 所以问一下谁有着方面的经验 讲讲 往DAT 文件里 我写的是一个结构体
 
TMSG = PACKED RECORD
DATETIME:TDATETIME;
UL:INTEGER;
IL:INTEGER;
ARRAY: ARRAY[0。。81] of BYTE;
END; 希望大家指点指点 别望我白白扔掉200分

解决方案 »

  1.   

    for i:=1 to 12 do //(12个下位机)
    begin
      send_msg;//
      congratulation:=recmsg;
      if congratulation=1 then 
      begin
        if(fileexists(ExtractFilePath(Application.EXEName)+'data\'+databasename+'.dat')) then
          begin
            try
              datStream := TRecordStream.Create(ExtractFilePath(Application.EXEName)+'data\'+databasename+'.dat', fmOpenWrite or fmShareDenyNone)
            except
            end;
          end
          else
          begin
            datStream := TRecordStream.Create(ExtractFilePath(Application.EXEName)+'data\'+databasename+'.dat', fmCreate);
                FileSetAttr(ExtractFilePath(Application.EXEName)+'data\'+databasename+'.dat', faHidden);
          end;
          datStream.Seek(0, 2);
          try
            datStream.Write(MsgRec,sizeof(MsgRec)); //我怀疑在这里出了毛病 
          except
          end;
          try
            datStream.Free;
          except
          end;
        
      end; 
    end;
      

  2.   

    for i:=1 to 12 do //(12个下位机)
    begin
      send_msg;//发送命令
      congratulation:=recmsg;//返回命令函数 根据返回的值赋给congratulation 决定如何处理数据
      if congratulation=1 then 
      begin
        if(fileexists(ExtractFilePath(Application.EXEName)+'data\'+databasename+'.dat')) then
          begin
            try
              datStream := TRecordStream.Create(ExtractFilePath(Application.EXEName)+'data\'+databasename+'.dat', fmOpenWrite or fmShareDenyNone)
            except
            end;
          end
          else
          begin
            datStream := TRecordStream.Create(ExtractFilePath(Application.EXEName)+'data\'+databasename+'.dat', fmCreate);
                FileSetAttr(ExtractFilePath(Application.EXEName)+'data\'+databasename+'.dat', faHidden);
          end;
          datStream.Seek(0, 2);
          try
            datStream.Write(MsgRec,sizeof(MsgRec)); //我怀疑在这里出了毛病 
          except
          end;
          try
            datStream.Free;
          except
          end;
        
      end; 
    end;
      

  3.   

    并发的情况??我想是没有 我用一个timer控制而且过去拿数据库做后台的时候一点问题都没有 只是换成了 DAT文件 就变成这样的毛病了
      

  4.   

    猜测是频繁判断磁盘文件造成的: (想当然的写了一下)
    var
      ...  
      DatName:string;
    begin
      DatName:='.\data\'+databasename+'.dat';
      if FileExists(DatName) then
        datStream := TRecordStream.Create(DatName, fmOpenWrite or fmShareDenyNone)
      else
        datStream := TRecordStream.Create(DatName, fmCreate);
      for i:=1 to 12 do
        begin
        send_msg;
        congratulation:=recmsg;
        if congratulation=1 then
          begin
          datStream.Seek(0, 2);
          datStream.Write(MsgRec,sizeof(MsgRec));
          end;
        end;
      datStream.close;
      datStream.free;
      

  5.   

    这几天正想研究文件的读写
    学习ing!
      

  6.   

    Tensionli() :初始化什么概念? chenylin(陈SIR):1,过去我也是频繁判断数据库的某个表存在不存在的 当然可能有所不同 
               2,我是一个下位机接受的数据存放到一个DAT文件里 也就是说DatName根据i的值变化的
                而你的代码是都写到一个文件里 因为涉及到每个下位机数据的浏览等等所以
                把所有的数据都保存到一个文件里是不太可行的
      

  7.   

    DAT 文件可以通过TClientDataSet来存取嘛!
      

  8.   

    你确定Record在写入之前是不含有0的参数吗?其实最好的解决办法就是,换条路走,用FileStream,建个函数处理Record的写入。例如
    procedure WriteRecordToStream(st: TFileStream; rec: TMSG);
    begin
      st.Write(rec.xxx);
      ...
    end;
    迅速搞定问题后,再写demo去验证是不是RecordStream读写有问题。
      

  9.   

    MsgRec:TMSG;
    chuchu(维他命C) :至少日期时间永远不会为0值 别的参数都是电力参数 基本上几乎永远不会为0  你的办法和我的办法有什么不同吗??
      

  10.   

    程序中
    datStream.Seek(0, 2);
    不知道什么意思还有MsgRec是什么东西啊,你怎么定义的?
    我想下面这句应该是这样写吧?
    datStream.Write(MsgRec,sizeof(MsgRec)); 假如MsgRec是TMSG  
    datStream.Write(MsgRec,sizeof(TMSG )); LZ可以试试。
      

  11.   

    datStream.Write(MsgRec,sizeof(MsgRec)); //我怀疑在这里出了毛病 
    这里通常应该是取MsgRec得结构定义:TMSG ,但是应该不会是这里得问题;因为你可以试试showmessage(SizeOf(MsgRec))和sizeOf(TMSG )建议你检查congratulation:=recmsg;得recmsg 函数,效验数据是否合法;从这些代码上看不出什么;也许看看你得数据文件会有启发
      

  12.   

    TO TANG1981:
      datStream.Seek(0, 2);就是文件的末尾 替换??可以吧 但是我的程序只是在运行来来回回这样插入几万次 甚至几十万次后 偶尔的出的毛病 软件在这段时间内除了收了这组0的参数外 其他一切正常 根本看不出来任何问题  S.F.:datStream.Write(MsgRec,sizeof(MsgRec)); 你怀疑这里出了毛病 这和我一样 但是却一点毛病看不出来 我现在还在怀疑这里的问题 仍旧探索中 傻中 呵呵 congratulation:=recmsg;得recmsg 函数 我保证没有毛病 因为原来的后台用数据库的时候 就用这个函数 没有任何问题 一天的数据有4万条左右 我用两天看了一遍 和解析前 从文件里读的完全是一个内容 哎呀谢谢大家 实在不行 就换成DELPHI的桌面数据库 我发现它特别优秀!如果这个问题过几天还解决不了 我再揭贴 真不好意思 就200分给大家
      

  13.   

    1. 在读写文件时, 最好加把锁(用 LockFileEx, UnlockFileEx 函数);2. 使用 FlushFileBuffers 函数把缓冲区内容写入磁盘. 因为调用 write 函数时,
    并不一定真正写入磁盘, 而一般是放在缓冲区中.3. 上面几个函数的文件句柄, 可以直接使用 TFileStream 的 Handle 属性.试试看?
      

  14.   

    TO kyee:  我的软件一天几乎插入记录在48万左右 这个错误是偶尔出现的 三五个小时 三五天 但是甚至三五个月都没有问题  根据你的建议 十一长假过后 我再谢谢看 谢谢你提供一个新思路!楼上的朋友 谢谢大家 其实来这里想大家讨教 根据我的描述 也就是求个思路,想法什么的 谢谢我正在打算换成桌面数据库 发现.DB文件与DELPHI结合 速度那是超级快 揭贴 过节 问候一下 呵呵~~