Unix-строки (чтение и запись Unix-файлов)

Previous  Top  Next

    
 

 

 

Code:

unit StreamFile;

 

interface

 

uses SysUtils;

 

procedure AssignStreamFile(var F: Text; Filename: string);

 

implementation

 

const

BufferSize = 128;

 

type

TStreamBuffer = array[1..High(Integer)] of Char;

TStreamBufferPointer = ^TStreamBuffer;

TStreamFileRecord = record

   case Integer of

     1:

     (

       Filehandle: Integer;

       Buffer: TStreamBufferPointer;

       BufferOffset: Integer;

       ReadCount: Integer;

       );

     2:

     (

       Dummy: array[1..32] of Char

       )

end;

 

function StreamFileOpen(var F: TTextRec): Integer;

var

Status: Integer;

begin

with TStreamFileRecord(F.UserData) do

   begin

     GetMem(Buffer, BufferSize);

     case F.Mode of

       fmInput:

         FileHandle := FileOpen(StrPas(F.Name), fmShareDenyNone);

       fmOutput:

         FileHandle := FileCreate(StrPas(F.Name));

       fmInOut:

         begin

           FileHandle := FileOpen(StrPas(F.Name), fmShareDenyNone or

             fmOpenWrite or fmOpenRead);

           if FileHandle <> -1 then

             status := FileSeek(FileHandle, 0, 2); { Перемещаемся в конец файла. }

           F.Mode := fmOutput;

         end;

     end;

     BufferOffset := 0;

     ReadCount := 0;

     F.BufEnd := 0; { В этом месте подразумеваем что мы достигли конца файла (eof). }

     if FileHandle = -1 then

       Result := -1

     else

       Result := 0;

   end;

end;

 

function StreamFileInOut(var F: TTextRec): Integer;

 

procedure Read(var Data: TStreamFileRecord);

   procedure CopyData;

   begin

     while (F.BufEnd < Sizeof(F.Buffer) - 2)

       and (Data.BufferOffset <= Data.ReadCount)

       and (Data.Buffer[Data.BufferOffset] <> #10) do

       begin

         F.Buffer[F.BufEnd] := Data.Buffer^[Data.BufferOffset];

         Inc(Data.BufferOffset);

         Inc(F.BufEnd);

       end;

     if Data.Buffer[Data.BufferOffset] = #10 then

       begin

         F.Buffer[F.BufEnd] := #13;

         Inc(F.BufEnd);

         F.Buffer[F.BufEnd] := #10;

         Inc(F.BufEnd);

         Inc(Data.BufferOffset);

       end;

   end;

 

begin

   F.BufEnd := 0;

   F.BufPos := 0;

   F.Buffer := '';

   repeat

     begin

       if (Data.ReadCount = 0) or (Data.BufferOffset > Data.ReadCount) then

         begin

           Data.BufferOffset := 1;

           Data.ReadCount := FileRead(Data.FileHandle, Data.Buffer^, BufferSize);

         end;

       CopyData;

   end until (Data.ReadCount = 0)

   or (F.BufEnd >= Sizeof(F.Buffer) - 2);

   Result := 0;

end;

 

procedure Write(var Data: TStreamFileRecord);

var

   Status: Integer;

   Destination: Integer;

   II: Integer;

begin

   with TStreamFileRecord(F.UserData) do

     begin

       Destination := 0;

       for II := 0 to F.BufPos - 1 do

         begin

           if F.Buffer[II] <> #13 then

             begin

               Inc(Destination);

               Buffer^[Destination] := F.Buffer[II];

             end;

         end;

       Status := FileWrite(FileHandle, Buffer^, Destination);

       F.BufPos := 0;

       Result := 0;

     end;

end;

begin

case F.Mode of

   fmInput:

     Read(TStreamFileRecord(F.UserData));

   fmOutput:

     Write(TStreamFileRecord(F.UserData));

end;

end;

 

function StreamFileFlush(var F: TTextRec): Integer;

begin

Result := 0;

end;

 

function StreamFileClose(var F: TTextRec): Integer;

begin

with TStreamFileRecord(F.UserData) do

   begin

     FreeMem(Buffer);

     FileClose(FileHandle);

   end;

Result := 0;

end;

 

procedure AssignStreamFile(var F: Text; Filename: string);

begin

with TTextRec(F) do

   begin

     Mode := fmClosed;

     BufPtr := @Buffer;

     BufSize := Sizeof(Buffer);

     OpenFunc := @StreamFileOpen;

     InOutFunc := @StreamFileInOut;

     FlushFunc := @StreamFileFlush;

     CloseFunc := @StreamFileClose;

     StrPLCopy(Name, FileName, Sizeof(Name) - 1);

   end;

end;

end.

 

 

©Drkb::00146

Взято из Советов по Delphi от Валентина Озерова

Сборник Kuliba