流的源代码

  TStringStream = class(TStream)  //字符串流
  private
    FDataString: string;  //内存的数据
    FPosition: Integer;
  protected
    procedure SetSize(NewSize: Longint); override;
  public
    constructor Create(const AString: string);
    function Read(var Buffer; Count: Longint): Longint; override;
    function ReadString(Count: Longint): string;
    function Seek(Offset: Longint; Origin: Word): Longint; override;
    function Write(const Buffer; Count: Longint): Longint; override;
    procedure WriteString(const AString: string);
    property DataString: string read FDataString;
  end;

procedure TStringStream.SetSize(NewSize: Longint);
begin
  SetLength(FDataString, NewSize);  //给字符串分配空间, 如果是缩小空间,那么还要改变字符串的当前位置
  if FPosition > NewSize then FPosition := NewSize;
end;

 

function TStringStream.Write(const Buffer; Count: Longint): Longint;//字符串流的写函数
begin
  Result := Count;//扩大字符串的长度,复制内容,移动字符串流的指针。
  SetLength(FDataString, (FPosition + Result));
  Move(Buffer, PChar(@FDataString[FPosition + 1])^, Result);
  Inc(FPosition, Result);
end;

 

function TStringStream.Read(var Buffer; Count: Longint): Longint; //字符串的读和写方法, 返回为实际读的字节数
begin
  Result := Length(FDataString) - FPosition; //字符串从当前位置能读的字节数
  if Result > Count then Result := Count; //矫正输入的参数。不能超过字符串的长度
  Move(PChar(@FDataString[FPosition + 1])^, Buffer, Result); //复制内容到Buffer中。并移动指针。
  Inc(FPosition, Result);
end;

 

function TStringStream.ReadString(Count: Longint): string; //读字符串和写字符串
var
  Len: Integer;
begin
  Len := Length(FDataString) - FPosition; //从当前位置能读的字符串的最大长度。
  if Len > Count then Len := Count;
  SetString(Result, PChar(@FDataString[FPosition + 1]), Len);
  Inc(FPosition, Len);
end;

procedure TStringStream.WriteString(const AString: string);
begin
  Write(PChar(AString)^, Length(AString));
end;

// 调用写方法。

 

procedure TStringStream.SetSize(NewSize: Longint);
begin
  SetLength(FDataString, NewSize);
  if FPosition > NewSize then FPosition := NewSize;
end;

扩大字符串流的大小。

 

//调整字符串的当前位置。

function TStringStream.Seek(Offset: Longint; Origin: Word): Longint;
begin
  case Origin of
    soFromBeginning: FPosition := Offset;
    soFromCurrent: FPosition := FPosition + Offset;
    soFromEnd: FPosition := Length(FDataString) - Offset;
  end;
  if FPosition > Length(FDataString) then
    FPosition := Length(FDataString)
  else if FPosition < 0 then FPosition := 0;
  Result := FPosition;
end;

 

procedure TForm1.Button1Click(Sender: TObject);
var
  Stream: TStringStream;
  Count, Pos: Integer;
  str: String;
begin
  Stream := TStringStream.Create('');
  Stream.WriteString('abc');
  Count := Stream.Seek(0, soFromEnd);
  Pos := Count;
  self.Memo1.Lines.Clear;
  while (Stream.Seek(Pos, soFromBeginning) <> 0) do
  Begin
    dec(Pos);
    Stream.Seek(Pos, soFromBeginning);
    Str := Stream.ReadString(Count - Pos);
    Memo1.Lines.Add(Str);
  end;
  ShowMessage(Stream.DataString);
end;

从中可以看出TStringStream实现了流才抽象方法Read, Write, Seek方法。

加上了自定义的方法。ReadString和WriteString.

 

  TCustomMemoryStream = class(TStream)
  private
    FMemory: Pointer; //存放数据的地址是一个指针.使用分配内存的方式来操作内存流
    FSize, FPosition: Longint;
  protected
    procedure SetPointer(Ptr: Pointer; Size: Longint);
  public
    function Read(var Buffer; Count: Longint): Longint; override;
    function Seek(Offset: Longint; Origin: Word): Longint; override;
    procedure SaveToStream(Stream: TStream);
    procedure SaveToFile(const FileName: string);
    property Memory: Pointer read FMemory;//返回内存的地址。
  end;

 

与字符串流一样,需要自己处理指针位置。

function TCustomMemoryStream.Seek(Offset: Longint; Origin: Word): Longint;
begin
  case Origin of
    soFromBeginning: FPosition := Offset;
    soFromCurrent: Inc(FPosition, Offset);
    soFromEnd: FPosition := FSize + Offset;
  end;
  Result := FPosition;
end;

 

//从载入流

procedure TMemoryStream.LoadFromStream(Stream: TStream);
var
  Count: Longint;
begin
  Stream.Position := 0;
  Count := Stream.Size;
  SetSize(Count);
  if Count <> 0 then Stream.ReadBuffer(FMemory^, Count);
end;

 

procedure TMemoryStream.LoadFromFile(const FileName: string);
var
  Stream: TStream;
begin
  Stream := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite);
  try
    LoadFromStream(Stream);
  finally
    Stream.Free;
  end;
end;

 

procedure TCustomMemoryStream.SetPointer(Ptr: Pointer; Size: Longint);
begin
  FMemory := Ptr;
  FSize := Size;
end;

设置内存流

procedure TCustomMemoryStream.SetPointer(Ptr: Pointer; Size: Longint);
begin
  FMemory := Ptr;
  FSize := Size;
end;

    function Read(var Buffer; Count: Longint): Longint; virtual; abstract;
    function Write(const Buffer; Count: Longint): Longint; virtual; abstract;
    function Seek(Offset: Longint; Origin: Word): Longint; overload; virtual;
    function Seek(const Offset: Int64; Origin: TSeekOrigin): Int64; overload; virtual;
    procedure ReadBuffer(var Buffer; Count: Longint);
    procedure WriteBuffer(const Buffer; Count: Longint);

文件流实现的两个方法就是Write, Read方法.

 

procedure TMemoryStream.LoadFromStream(Stream: TStream);
var
  Count: Longint;
begin
  Stream.Position := 0;
  Count := Stream.Size;
  SetSize(Count);
  if Count <> 0 then Stream.ReadBuffer(FMemory^, Count);
end;

procedure TMemoryStream.LoadFromFile(const FileName: string);
var
  Stream: TStream;
begin
  Stream := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite);
  try
    LoadFromStream(Stream);
  finally
    Stream.Free;
  end;
end;

载入内存流的方法。

 

写如内存流

function TMemoryStream.Write(const Buffer; Count: Longint): Longint;
var
  Pos: Longint;
begin
  if (FPosition >= 0) and (Count >= 0) then
  begin
    Pos := FPosition + Count;
    if Pos > 0 then
    begin
      if Pos > FSize then
      begin
        if Pos > FCapacity then
          SetCapacity(Pos);
        FSize := Pos;
      end;
      System.Move(Buffer, Pointer(Longint(FMemory) + FPosition)^, Count);
      FPosition := Pos;
      Result := Count;
      Exit;
    end;
  end;
  Result := 0;
end;

 

//流总是创建。

function FileCreate(const FileName: string): Integer;
{$IFDEF MSWINDOWS}
begin
  Result := Integer(CreateFile(PChar(FileName), GENERIC_READ or GENERIC_WRITE,
    0, nil, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0));
end;
{$ENDIF}
{$IFDEF LINUX}
begin
  Result := FileCreate(FileName, FileAccessRights);
end;
{$ENDIF}

function FileCreate(const FileName: string; Rights: Integer): Integer;
{$IFDEF MSWINDOWS}
begin
  Result := FileCreate(FileName);
end;
{$ENDIF}
{$IFDEF LINUX}
begin
  Result := Integer(open(PChar(FileName), O_RDWR or O_CREAT or O_TRUNC, Rights));
end;
{$ENDIF}

 

On Windows:

  const

    fmCreate         = $FFFF;
    fmOpenRead       = $0000;
    fmOpenWrite      = $0001;
    fmOpenReadWrite  = $0002;

    fmShareCompat    = $0000 platform;
    fmShareExclusive = $0010;
    fmShareDenyWrite = $0020;
    fmShareDenyRead  = $0030 platform;
    fmShareDenyNone  = $0040;

On Linux:

  const

    fmOpenRead       = O_RDONLY;
    fmOpenWrite      = O_WRONLY;
    fmOpenReadWrite  = O_RDWR;
    fmShareExclusive = $0010;
    fmShareDenyWrite = $0020;
    fmShareDenyNone  = $0030;

C++ syntax:

static const Word fmCreate = 0xffff;

static const Shortint fmOpenRead = 0x0;
static const Shortint fmOpenWrite = 0x1;
static const Shortint fmOpenReadWrite = 0x2;
static const Shortint fmShareCompat = 0x0;
static const Shortint fmShareExclusive = 0x10;
static const Shortint fmShareDenyWrite = 0x20;
static const Shortint fmShareDenyRead = 0x30;
static const Shortint fmShareDenyNone = 0x40;

Description

The file open mode constants are used when a file or stream is opened to control how it can be shared.

The TFileStream constructor has a Mode parameter that you can set to one of these constants:

Constant Definition

fmCreate If the file exists, open for write access, otherwise, create a new file. Unlike the other constants, which are declared in the SysUtils unit, this constant is declared in tge classes unit.
fmOpenRead Open for read access only.
fmOpenWrite Open for write access only.
fmOpenReadWrite Open for read and write access.
fmShareCompat Compatible with the way FCBs are opened. Do not use this mode in cross-platform applications.
fmShareExclusive Read and write access is denied.

fmShareDenyWrite Write access is denied.
fmShareDenyRead Read access is denied. Do not use this mode in cross-platform applications.
fmShareDenyNone Allows full access for others.

原文链接: https://www.cnblogs.com/abcliu110/archive/2010/11/13/1876640.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

    流的源代码

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/17372

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月7日 下午5:54
下一篇 2023年2月7日 下午5:55

相关推荐