请教iseek大侠(0分)

  • 主题发起人 主题发起人 zuoc
  • 开始时间 开始时间
Z

zuoc

Unregistered / Unconfirmed
GUEST, unregistred user!
stm.AddAData('1', '',ms1);
stm.AddAData('2', '',ms2);
stm.AddAData('3', '',ms3);
stm.ReadAData(1,ms);//可以读出
stm.ReadAData(2,ms);//可以读出
//但
stm.ReadAData(0,ms);//报错‘Mismatch in datapacket’
 
我刚才做的测试,可以啊.要不你把你的完整的代码贴出来看看.
从提示来看,是datapacket不匹配,应该不是TStreamPack造成的.

procedure TForm1.Button2Click(Sender: TObject);
var smt:tstreampack;
s:string;
ms:tmemorystream;
begin
smt:=tstreampack.Create;
ms:=tmemorystream.Create;

s:='aaaaa';
string2stream(s,ms);//这是我自己的一个函数
smt.AddAData('1','',ms);
ms.Clear;

s:='bbbbb';
string2stream(s,ms);
smt.AddAData('2','',ms);
ms.Clear;

s:='ccccc';
string2stream(s,ms);
smt.AddAData('3','',ms);
ms.Clear;

smt.ReadAData(0,ms);
stream2string(ms,s);
showmessage(s);//显示为"aaaaa"

smt.Free;
ms.Free;
end;
 
iseek 顾名思义 专攻流的 呵呵
 
procedure TForm1.Button1Click(Sender: TObject);
var
stm: TStreamPack;
a, b, c,d: Tmemorystream;
a1:Tmemorystream;
begin
a := Tmemorystream.Create;
b := Tmemorystream.Create;
d := Tmemorystream.Create;
try
ClientDataSet1.SaveToStream(a);
ClientDataSet2.SaveToStream(b);
ClientDataSet4.SaveToStream(d);
stm := TStreamPack.Create;
try
stm.AddAData('1', '', a);
stm.AddAData('2', '', b);
stm.AddAData('3', '', d);
c := Tmemorystream.Create;
try
stm.SaveToStream(c);

kbmMemTable1.Append;
kbmMemTable1.FieldByName('id').AsString := 'c';
TBlobField(kbmMemTable1.FieldByName('strm')).LoadFromStream(c);
kbmMemTable1.Post;
finally
c.Free;
end;
finally
stm.Free;
end;
finally
a.Free;
b.Free;
d.Free;
end;
end;

procedure TForm1.BitBtn1Click(Sender: TObject);
var
stm: TStreamPack;
a1, b1, c1: Tmemorystream;
ms: TStream;
i:integer;
begin
stm := TStreamPack.Create;
try
ms := kbmMemTable1.CreateBlobStream(kbmMemTable1.FieldByName('strm'), bmread);
try
b1 := Tmemorystream.Create;
try
ms.Position:=0;
b1.LoadFromStream(ms);
stm.LoadFromStream(b1, '');
finally
b1.Free;
end;
a1 := Tmemorystream.Create;
try
i:=stm.IDExists('1')
//如果为‘1’就出错,‘2’和‘3’正确
stm.ReadAData(i, a1);
a1.Position:=0;
ClientDataSet3.LoadFromStream(a1);
ClientDataSet3.Open;
finally
a1.Free;
end;
finally
ms.Free;
end;
finally
stm.Free;
end;
end;
 
呵呵.冰力不足笑话我.
我是个业余玩票的.

to zuoc
不好意思,我仔细的看了一下,是我的那类有问题.当时反复修改,版本多到自己都晕了,结果发出来的竟然是有问题的.
下面的这个是我从硬盘里找的,带DEMO.如果需要DEMO,留个妹儿,我发给你.要说明的是,有个MyUnit的单元是坏的,因为D盘曾不小心被格了,用恢复工具恢复后,这个单元损坏了.好在它的dcu没问题,照样可以编译.
------------------------------------------------------------------------------
//------------------------------------------------------------------------------
//功 能:将若干个流合并成一个流,可以对其进行读出添加删除操作以及输出为文件
// 或流。
//作 者:iseek
//开始时间:2005.07.25
//最后修改:2005.07.30
//E-mail : iatgog@gmail.com
//------------------------------------------------------------------------------
unit StreamPack;

interface
uses classes, Sysutils, windows, Gauges, Dialogs;

type
TFileHead = record
FileMark: array[0..5] of char;
StreamLen: longint;
StreamNum: word;
end;

PDataHead = ^TDataHead;
TDataHead = record
DataName: array[0..39] of char;
DataType: array[0..7] of char;
DataPass: array[0..7] of char;
DataSize: longint;
DataPos: longint;
end;

TStreamPack = class
private
FDataList: TList;
FFileHead: TFileHead;
FDataHead: TDataHead;
FStream: TMemoryStream;
FFileName: string
//文件名
FStreamName: string
//流名
FValidSize: longint;
FTempName: string
//临时文件名
FTempIndex: string
//临时索引名
FModified: boolean;
FFHModified: boolean
//文件头变动标志
FTempData: boolean;
FTempDataHead: boolean;

procedure SetModified(Value: boolean);
procedure SetStreamName(Value: string);
function GetValidSize: longint;

function LoadList: boolean;
procedure BindList(ds: TMemoryStream);
procedure SaveFileHead;
procedure SaveListToStream(ms: TMemoryStream);
procedure ClearList;
procedure ChangeDataPos(idx: integer);
procedure StreamDelete(AStream: TStream
Index: Longint
Count: Longint);
public
property FileHead: TFileHead read FFileHead write FFileHead;
property DataHead: TDataHead read FDataHead write FDataHead;
property DataList: TList read FDataList;
property FileName: string read FFileName;
property Modified: boolean read FModified write SetModified default false;
property StreamName: string read FStreamName write SetStreamName;
property ValidSize: longint read GetValidSize default 0;

constructor Create;
destructor Destroy
override;

procedure CreateStreamPack(const fn: string
OnlyStream: boolean);
procedure Clear;
function LoadFromFile(const fn: string): boolean;
function LoadFromStream(ms: TMemoryStream
dn: string): boolean;
procedure Save;
procedure SaveToFile(const fn: string);
procedure SaveToStream(ms: TMemoryStream);
procedure TempSaveData;
procedure TempSaveHead;

function ReadAData(idx: integer
ds: TMemoryStream): boolean;
procedure DeleteAData(idx: integer);
procedure DelADataAtOnce(idx: integer);
function AddAData(const ID, Ext: string
src: TMemoryStream): boolean;
procedure ReNameAData(idx: integer
NewID: string);
function IDExists(ID: string): integer;

procedure CompressData(g: TGauge);
procedure SetStreamSize(size: longint);
function ItemsStrForOuter: string;
procedure ExportAllItems(g: TGauge
path: string);

procedure SaveListToFile(fn: string);
end;

implementation

const
iExt = '.pac';
sLoadError = '不正确的文件格式或文件已损坏。';
sDefaultPS = 'wuping';


function TStreamPack.AddAData(const ID, Ext: string
src: TMemoryStream): boolean;
var pd: PDataHead;
sz: longint;
num: word;
begin
Result := true;
try
New(pd);
StrPCopy(pd^.DataName, ID);
StrPCopy(pd^.DataType, Ext);
pd^.DataPass[0] := #0;
pd^.DataSize := src.Size;
pd^.DataPos := FStream.Size;
FDataList.Add(pd);

if FTempData then
begin
FStream.LoadFromFile(FTempName);
FTempData := false;
end;
FStream.Seek(0, soFromEnd);
FStream.CopyFrom(src, 0);
sz := FFileHead.StreamLen;
sz := sz + src.Size;
FFileHead.StreamLen := sz;
num := FFileHead.StreamNum;
inc(num);
FFileHead.StreamNum := num;
FModified := true;
FFHModified := true;
except
Result := false;
end;
end;

procedure TStreamPack.BindList(ds: TMemoryStream);
var ms: TMemoryStream;
begin
SaveFileHead;
ms := TMemoryStream.Create;
try
SaveListToStream(ms);
ds.SetSize(FStream.Size + ms.Size);
ds.CopyFrom(FStream, 0);
//ds.Seek(0,soFromEnd);
ds.CopyFrom(ms, 0);
finally
ms.Free;
end;
end;

procedure TStreamPack.Clear;
begin
if (FModified) or (FFHModified) then Save;
FFileName := '';
FStreamName := '';
FModified := false;
FFHModified := false;
FTempData := false;
FTempDataHead := false;
if FileExists(FTempName) then DeleteFile(PChar(FTempName));
FTempName := '';
if FileExists(FTempIndex) then DeleteFile(PChar(FTempIndex));
FTempIndex := '';
ClearList;
FFileHead.StreamLen := 0;
FFileHead.StreamNum := 0;
end;

procedure TStreamPack.CompressData(g: TGauge);
var pd: PDataHead;
i: integer;
size: longint;
ms: TMemoryStream;
begin
if FDataList.Count = 0 then exit;
if FFileHead.StreamNum = FDataList.Count then exit;
if FTempData then
begin
FStream.LoadFromFile(FTempName);
FTempData := false;
end;
g.MinValue := 0;
g.MaxValue := FDataList.Count - 1;
ms := TMemoryStream.Create;
try
FFileHead.StreamLen := SizeOf(TFileHead) + FValidSize;
FFileHead.StreamNum := FDataList.Count;
ms.SetSize(FValidSize);
for i := 0 to FDataList.Count - 1 do
begin
g.Progress := i;
pd := FDataList.Items;
FStream.Position := pd^.DataPos;
ms.CopyFrom(FStream, pd^.DataSize);
end;
ChangeDataPos(0);
FStream.Clear;
FStream.SetSize(SizeOf(TFileHead) + ms.Size + SizeOf(TDataHead) * FDataList.Count);
FStream.Position := 0;
FStream.Write(FFileHead, SizeOf(TFileHead));
FStream.CopyFrom(ms, 0);
size := FStream.Size;
ms.Clear;
SaveListToStream(ms);
if FFileName <> '' then
begin
FStream.CopyFrom(ms, 0);
FStream.SaveToFile(FFileName);
FStream.SetSize(size);
FModified := false;
FFHModified := false;
end else
begin
FModified := true;
FFHModified := true;
end;
finally
ms.Free;
end;
end;

constructor TStreamPack.Create;
begin
inherited Create;
FStream := TMemoryStream.Create;
FDataList := TList.create;
FTempData := false;
FTempDataHead := false;
FFHModified := false;
end;

procedure TStreamPack.CreateStreamPack(const fn: string
OnlyStream: boolean);
begin
if FDataList.Count > 0 then clear;
StrPCopy(FFileHead.FileMark, sDefaultPS);
FFileHead.StreamLen := SizeOf(TFileHead);
FFileHead.StreamNum := 0;
FStream.Write(FFileHead, SizeOf(TFileHead));
if not OnlyStream then
begin
FStream.SaveToFile(fn);
FFileName := fn;
end;
end;

procedure TStreamPack.DeleteAData(idx: integer);
var pd: PDataHead;
begin
pd := FDataList.Items[idx];
Dispose(pd);
FDataList.Delete(idx);
FModified := true;
end;

destructor TStreamPack.Destroy;
begin
Clear;
FDataList.Free;
FStream.Free;
inherited;
end;

procedure TStreamPack.ExportAllItems(g: TGauge
path: string);
var i: integer;
pd: PDataHead;
fn: string;
ms: TMemoryStream;
begin
if FDataList.Count = 0 then exit;
g.MinValue := 0;
g.MaxValue := FDataList.Count - 1;
ms := TMemoryStream.Create;
try
for i := 0 to FDataList.Count - 1 do
begin
g.Progress := i;
pd := FDataList.Items;
fn := path + pd^.DataName + pd^.DataType;
FStream.Seek(pd^.DataPos, soFromBeginning);
ms.CopyFrom(FStream, pd^.DataSize);
ms.SaveToFile(fn);
ms.Clear;
end;
finally
ms.Free;
end;
end;

function TStreamPack.GetValidSize: longint;
var i: integer;
pd: PDataHead;
begin
Result := 0;
if FDataList.Count = 0 then exit;
for i := 0 to FDataList.Count - 1 do
begin
pd := FDataList.Items;
Result := Result + pd^.DataSize;
end;
end;

function TStreamPack.IDExists(ID: string): integer;
var i: integer;
pd: PDataHead;
begin
Result := -1;
if FDataList.Count = 0 then exit;
for i := 0 to FDataList.Count - 1 do
begin
pd := FDataList.Items;
if pd^.DataName = ID then
begin
Result := i;
break;
end;
end;
end;

function TStreamPack.ItemsStrForOuter: string;
var i, count: integer;
pd: PDataHead;
begin
count := FDataList.Count;
if count = 0 then exit;
for i := 0 to count - 1 do
begin
pd := FDataList.Items;
Result := Result + pd^.DataName;
if i < count - 1 then Result := Result + #13#10;
end;
end;

function TStreamPack.LoadFromFile(const fn: string): boolean;
begin
Result := false;
if not FileExists(fn) then exit;
if FDataList.Count > 0 then clear;
FStream.LoadFromFile(fn);
if LoadList then
begin
FFileName := fn;
Result := true;
end;
end;

function TStreamPack.LoadFromStream(ms: TMemoryStream;
dn: string): boolean;
begin
Result := false;
if assigned(ms) then
begin
if FDataList.Count > 0 then clear;
FStream.LoadFromStream(ms);
if LoadList then
begin
FStreamName := dn;
Result := true;
end;
end;
end;

function TStreamPack.LoadList: boolean;
var pd: PDataHead;
i: integer;
count: word;
size: longint;
ds: TMemoryStream;
begin
Result := true;
try
FStream.Seek(0, soFromBeginning);
FStream.Read(FFileHead, SizeOf(TFileHead));
if FFileHead.StreamLen = SizeOf(TFileHead) then exit;
FStream.Seek(-SizeOf(size), soFromEnd);
Fstream.Read(size, SizeOf(size));
FStream.Seek(-(size + SizeOf(size)), soFromEnd);
ds := TMemoryStream.Create;
try
ds.CopyFrom(FStream, size);
ds.Seek(0, soFromBeginning);
ds.Read(count, SizeOf(count));
FDataList.Count := count;
for i := 0 to count - 1 do
begin
New(pd);
ds.Read(pd^, SizeOf(TDataHead));
FDataList.Items := pd;
end;
FStream.SetSize(FStream.Size - size - SizeOf(size));
finally
ds.Free;
end;
except
Result := false;
ShowMessage(sLoadError);
end;
end;

function TStreamPack.ReadAData(idx: integer
ds: TMemoryStream): boolean;
var pd: PDataHead;
begin
Result := true;
if FDataList.Count = 0 then exit;
pd := FDataList.Items[idx];
if FTempData then FStream.LoadFromFile(FTempName);
FStream.Position := pd^.DataPos;
ds.CopyFrom(FStream, pd^.DataSize);
end;

procedure TStreamPack.ReNameAData(idx: integer
NewID: string);
var pd: PDataHead;
begin
if FDataList.Count = 0 then exit;
pd := FDataList.Items[idx];
StrPCopy(pd^.DataName, NewID);
FModified := true;
end;

procedure TStreamPack.Save;
var ms: TMemoryStream;
begin
if FFileName = '' then exit;
ms := TMemoryStream.Create;
try
BindList(ms);
ms.SaveToFile(FFileName);
FModified := false;
FFHModified := false;
finally
ms.Free;
end;
end;

procedure TStreamPack.SaveToFile(const fn: string);
var ms: TMemoryStream;
begin
if FDataList.Count = 0 then exit;
ms := TMemoryStream.Create;
try
BindList(ms);
ms.SaveToFile(fn);
FModified := false;
FFHModified := false;
finally
ms.Free;
end;
end;

procedure TStreamPack.SaveToStream(ms: TMemoryStream);
begin
if FDataList.Count = 0 then exit;
BindList(ms);
ms.Position := 0;
end;

procedure TStreamPack.SetModified(Value: boolean);
begin
FModified := Value;
end;

procedure TStreamPack.SetStreamName(Value: string);
begin
FStreamName := Value;
end;

procedure TStreamPack.TempSaveData;
begin
if FStream.Size > SizeOf(TFileHead) then
begin
FStream.SaveToFile(FTempName);
FTempData := true;
FStream.Clear;
end;
end;

procedure TStreamPack.SaveListToStream(ms: TMemoryStream);
var i: integer;
n: word;
size: longint;
begin
n := FDataList.Count;
ms.Write(n, SizeOf(word));
for i := 0 to FDataList.Count - 1 do
ms.Write(PDataHead(FDataList.Items)^, SizeOf(TDataHead));
size := ms.Size;
ms.Write(size, SizeOf(size));
end;

procedure TStreamPack.TempSaveHead;
var ms: TMemoryStream;
begin
if FDataList.Count = 0 then exit;
ms := TMemoryStream.Create;
try
SaveListToStream(ms);
ms.SaveToFile(FTempIndex);
finally
ms.Free;
end;
end;

procedure TStreamPack.SaveFileHead;
begin
if FFHModified then
begin
FStream.Seek(0, soFromBeginning);
FStream.Write(FFileHead, SizeOf(TFileHead));
end;
end;

procedure TStreamPack.ClearList;
var pd: PDataHead;
i: integer;
begin
if FDataList.Count = 0 then exit;
for i := 0 to FDataList.Count - 1 do
begin
pd := FDataList.Items;
Dispose(pd);
end;
FDataList.Clear;
end;

procedure TStreamPack.SaveListToFile(fn: string);
var i: integer;
pd: PDataHead;
ts: TStringList;
begin
if FDataList.Count = 0 then exit;
ts := TStringList.Create;
try
for i := 0 to FDataList.Count - 1 do
begin
ts.Add('Data' + inttostr(i));
pd := FDataList.Items;
ts.Add('DataName:' + string(pd^.DataName));
ts.Add('DataExt:' + string(pd^.DataType));
ts.Add('DataPass:' + string(pd^.DataPass));
ts.Add('DataSize:' + inttostr(pd^.DataSize));
ts.Add('DataPos:' + inttostr(pd^.DataPos));
ts.Add('');
end;
ts.SaveToFile(fn);
finally
ts.Free;
end;
end;

procedure TStreamPack.ChangeDataPos(idx: integer);
var i: integer;
ipos: longint;
pd: PDataHead;
begin
if idx = 0 then ipos := SizeOf(TFileHead) else
begin
pd := FDataList.Items[idx - 1];
ipos := pd^.DataPos + pd^.DataSize;
end;
for i := idx to FDataList.Count - 1 do
begin
pd := FDataList.Items;
pd^.DataPos := ipos;
FDataList.Items := pd;
ipos := ipos + pd^.DataSize;
end;
end;

procedure TStreamPack.SetStreamSize(size: longint);
begin
FStream.SetSize(FValidSize + size);
end;

procedure TStreamPack.StreamDelete(AStream: TStream
Index, Count: Longint);
var
SavedPos: Longint;
ASize: Longint;
BufferStream: TMemoryStream;
begin
if not Assigned(AStream) then
exit;
ASize := AStream.Size;
if (Index >= ASize) or (Count = 0) then
exit;
if (Index + Count) >= ASize then
begin
AStream.Size := Index;
exit;
end
else begin
SavedPos := AStream.Position;
try
AStream.Seek(Index + Count, soFromBeginning);
BufferStream := TMemoryStream.Create;
try
ASize := ASize - (Index + Count);
BufferStream.SetSize(ASize);
BufferStream.Seek(0, soFromBeginning);
BufferStream.CopyFrom(AStream, ASize);
AStream.Size := Index + ASize;
AStream.Seek(Index, soFromBeginning);
AStream.Write(BufferStream.Memory^, ASize);
finally
BufferStream.Free;
end;
finally
AStream.Position := SavedPos;
end;
end;
end;

procedure TStreamPack.DelADataAtOnce(idx: integer);
var pd: PDataHead;
begin
pd := FDataList.Items[idx];
StreamDelete(FStream, pd^.DataPos, pd^.DataSize);
Dispose(pd);
FDataList.Delete(idx);
ChangeDataPos(idx);
FModified := true;
end;
 
zuoc@163.com
你现在这个TStreamPack没什么变化啊,问题依旧.
 
已把DEMO发给你.
我没有仔细对照两个单元的差别.如果DEMO没有问题,可能就需要找找是否有其它原因.可惜我对数据库不怎么熟,我自己编的小软件都是自己写的自定义数据库,帮不上你.
 
我刚才单独测试了一下,是可以的.
你可能要把原来的streampack.dcu文件删除,再重新编译.
 
后退
顶部