如何删除二进制流文件中的某条记录(小难)
比如第 i 条,谢谢,

解决方案 »

  1.   

    你有很多书放在箱子里(例如有5本),那么怎么把放在箱子里第3本书拿出来呢?首先你要把第5,4,3本拿出来,然后再把5,4放进去。
    删除记录也是类似的例如你有10条记录,要删除第4条,那么就要把,第5条记录写到第4条记录的位置,第6条写到第5条的位置,依此类推,
    当然最后第9和10条中都是原来第10条的信息,现在就要把文件缩短。
    使用API函数 SetEndofFile(FileStream.Handle);
    该API函数的作用是把流文件中当前指针所指向的位置设置为文件结束,所以,调用该函数时,你的记录指针应该指向第9条记录的结束出,第10条记录的开始处。ok,收工!
      

  2.   

    procedure tjzck_form.DStreamData(FileName:String; StartPos,EndPos: Integer);
    //StartPos: 从此开始“删除”信息,EndPos: 到此结束“删除”信息
    //如果输入文件名与输出文件名相同,就等于把源文件的StartPos与EndPos之间的内容删除
    下面程序中 mssr_stream 是原来的要删除记录的文件流,已经打开,请指出错误,谢谢
    var
      Tmp: TMemoryStream;
    begin
        try
    //      Ori := TFileStream.Create(FileName, fmOpenRead);
          Tmp := TMemoryStream.Create;
          Tmp.CopyFrom(mssr_stream, StartPos);
          //Tmp从Ori拷贝数据,但在StartPos与EndPos之间不拷,因此形同删除了一段数据
          mssr_stream.Seek(EndPos,soFromBeginning);
          Tmp.CopyFrom(mssr_stream, mssr_stream.Size-EndPos);
          Tmp.SaveToStream(mssr_stream);  //在此设置输出文件名
        finally
          FreeAndNil(Tmp);
        end;
    end;
      

  3.   

    你使用内存流临时存放文件有一个很大的坏处就是当文件很大的时候,太占内存了。
    procedure tjzck_form.DStreamData(FileName:String; StartPos,EndPos: Integer);
    var
      Buffer: array[0..10239] of Byte; //开辟1M缓存
      ReadCount, Pos1, Pos2: Integer;
    begin
        try
          Pos1 := StartPos;
          Pos2 := EndPos;
          repeat
            mssr_stream.Seek(Pos2,soFromBeginning);
            Pos2 := Pos2 + 10240;
            ReadCount := mssr_stream.Read(Buffer, 10240);
            if ReadCount > 0 then
            begin
              mssr_stream.Seek(Pos1, soFromBeginning);
              mssr_stream.Write(Buffer, 10240);
              Pos1 := Pos1 + 10240;
            end;  
          until ReadCount <= 0;
          mssr_stream.Seek(-(StartPos-EndPos), soFromEnd);
          SetEndOfFile(mssr_stream);
        finally
          mssr_stream.Free;
        end;
    end;
      

  4.   

    SetEndOfFile(mssr_stream);行错误如下,[Error] jzck_unit.pas(122): Incompatible types: 'Cardinal' and 'TRecordStream1'
      

  5.   

    我把SetEndOfFile(mssr_stream);屏蔽,
    执行后变成拷贝了一大堆乱码,。非常多
      

  6.   

    我把SetEndOfFile(mssr_stream) 改成 
    SetEndOfFile(mssr_stream.Handle); 
    还是一大堆乱码。谢谢
      

  7.   

    sorry!
    mssr_stream.Write(Buffer, 10240);改为:
    mssr_stream.Write(Buffer, ReadCount);SetEndOfFile(mssr_stream)改为SetEndOfFile(mssr_stream.Handle);
    再看看!嘻嘻,信手写不行,哎
      

  8.   

    哦!还要改一句
    Pos1 := Pos1 + ReadCount;没你那个流,没办法测试,真麻烦,再看看!