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 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174
| unit StreamRecord_MainForm;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
Memo1: TMemo;
procedure Button1Click(Sender: TObject);
private
{ Déclarations privées }
public
{ Déclarations publiques }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
type
TSrData = packed record
P1: array[1..7] of AnsiChar;
P2: array[1..10] of AnsiChar;
EOL: array[1..2] of AnsiChar;
end;
TSr = class(TObject)
private
FData: TSrData;
function GetP1(): AnsiString;
function GetP2(): AnsiString;
procedure SetP1(const Value: AnsiString);
procedure SetP2(const Value: AnsiString);
public
function LoadFromStream(AStream: TStream): Boolean;
procedure SaveToStream(AStream: TStream);
property P1: AnsiString read GetP1 write SetP1;
property P2: AnsiString read GetP2 write SetP2;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
SrW, SrR: TSr;
FS: TFileStream;
begin
FS := TFileStream.Create('SR.txt', fmCreate);
try
SrW := TSr.Create();
try
SrW.P1 := '1111111';
SrW.P2 := '3333333333';
SrW.SaveToStream(FS);
SrW.P1 := '2222222';
SrW.P2 := '4444444444';
SrW.SaveToStream(FS);
SrW.P1 := '777';
SrW.P2 := '55555';
SrW.SaveToStream(FS);
finally
SrW.Free();
end;
finally
FS.Free();
end;
FS := TFileStream.Create('SR.txt', fmOpenRead);
try
SrR := TSr.Create();
try
while SrR.LoadFromStream(FS) do
Memo1.Lines.Add(Format('P1: %s, P2: %s', [SrW.P1, SrW.P2]))
finally
SrR.Free();
end;
finally
FS.Free();
end;
end;
{ TSr }
function TSr.GetP1(): AnsiString;
begin
Result := FData.P1; // Conversion implicité d'un Array of Char en AnsiString
end;
function TSr.GetP2(): AnsiString;
begin
Result := FData.P2; // Conversion implicité d'un Array of Char en AnsiString
end;
function TSr.LoadFromStream(AStream: TStream): Boolean;
const
Delimiter: array[0..1] of AnsiChar = #13#10; // On peut aussi utiliser sLineBreak
var
LineLen: Integer;
begin
LineLen := SizeOf(FData);
Result := AStream.Position + LineLen <= AStream.Size;
// Version détaillée
(*
if Result then
begin
if AStream.Read(FData.P1[1], Length(FData.P1)) <> Length(FData.P1) then
Exit(False);
if AStream.Read(FData.P2[1], Length(FData.P2)) <> Length(FData.P2) then
Exit(False);
if (AStream.Read(FData.EOL[1], Length(Delimiter)) <> Length(Delimiter)) and or CompareMem(@FData.EOL[1], @Delimiter[0], Length(Delimiter)) then
Exit(False);
end;
*)
// Version One Shot
if Result then
if (AStream.Read(FData, LineLen) <> LineLen) or not CompareMem(@FData.EOL[1], @Delimiter[0], Length(Delimiter)) then
Exit(False);
end;
procedure TSr.SaveToStream(AStream: TStream);
const
Delimiter: array[0..1] of AnsiChar = #13#10; // On peut aussi utiliser sLineBreak
begin
// Version détaillée
(*
AStream.Write(FData.P1[1], Length(FData.P1));
AStream.Write(FData.P2[1], Length(FData.P2));
AStream.Write(Delimiter[0], Length(Delimiter));
*)
// Version One Shot
CopyMemory(@FData.EOL[1], @Delimiter[0], Length(Delimiter));
AStream.Write(FData, SizeOf(FData));
end;
procedure TSr.SetP1(const Value: AnsiString);
var
ValueLen, RawLen: Integer;
begin
ValueLen := Length(Value);
RawLen := Length(FData.P1);
// FillChar s'attend à un nombre d'octets !
if RawLen > ValueLen then
FillChar(FData.P1[ValueLen], RawLen - ValueLen + 1, ' ');
// Copie de la valeur
CopyMemory(@FData.P1[1], @Value[1], ValueLen);
end;
procedure TSr.SetP2(const Value: AnsiString);
var
ValueLen, RawLen: Integer;
begin
ValueLen := Length(Value);
RawLen := Length(FData.P2);
// FillChar s'attend à un nombre d'octets !
if RawLen > ValueLen then
FillChar(FData.P2[ValueLen], RawLen - ValueLen + 1, ' ');
// Copie de la valeur
CopyMemory(@FData.P2[1], @Value[1], ValueLen);
end;
end. |
Partager