скрыть

скрыть

  Форум  

Delphi FAQ - Часто задаваемые вопросы

| Базы данных | Графика и Игры | Интернет и Сети | Компоненты и Классы | Мультимедиа |
| ОС и Железо | Программа и Интерфейс | Рабочий стол | Синтаксис | Технологии | Файловая система |



Google  
 

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



Противоламерская Оборона, имею медаль"За защиту UNIX'а от Мелкомягких"

Данный модуль позволяет читать и записывать файлы формата Unix.


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.






Copyright © 2004-2016 "Delphi Sources". Delphi World FAQ




Группа ВКонтакте   Ссылка на Twitter   Группа на Facebook