prog

xfile.pas

Aug 15th, 2010
59
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Delphi 4.04 KB | None | 0 0
  1. unit xfile;
  2.  
  3. {$I cubix.inc}
  4.  
  5. interface
  6.  
  7. uses
  8.   Windows,
  9.   Messages,
  10.   WinSock,
  11.   SysUtils,
  12.   Classes,
  13.   fifostream;
  14.  
  15. const
  16.   MAX_BUFFER = 1024 * 32;
  17.  
  18. type
  19.   TFileReadEvent = procedure(Sender: TObject; const Buffer; Count: Integer) of object;
  20.  
  21.   TAsyncFile = class
  22.   private
  23.     FHandle: THandle;
  24.     FReadPending: Boolean;
  25.     FOverlapped: TOverlapped;
  26.     FBuffer: Pointer;
  27.     FBufferSize: Integer;
  28.     FOnRead: TFileReadEvent;
  29.     FEof: Boolean;
  30.     FSize: Integer;
  31.     function ProcessIo: Boolean;
  32.     procedure DoOnRead(Count: Integer);
  33.     function GetOpen: Boolean;
  34.   public
  35.     constructor Create(Filename: string; BufferSize: Integer = MAX_BUFFER);
  36.     destructor Destroy; override;
  37.     procedure BeginRead;
  38.     procedure Seek(Position: Integer);
  39.     procedure Close;
  40.     property OnRead: TFileReadEvent read FOnRead write FOnRead;
  41.     property Eof: Boolean read FEof;
  42.     property IsOpen: Boolean read GetOpen;
  43.     property Size: Integer read FSize;
  44.   end;
  45.  
  46. function ProcessFiles: Boolean;
  47.  
  48. implementation
  49.  
  50. var
  51.   Files: TList;
  52.  
  53. function ProcessFiles: Boolean;
  54. var
  55.   i: Integer;
  56.   AsyncFile: TAsyncFile;
  57. begin
  58.   Result := False;
  59.   for i := Files.Count - 1 downto 0 do
  60.   begin
  61.     AsyncFile := TAsyncFile(Files[i]);
  62.     Result := AsyncFile.ProcessIo or Result;
  63.   end;
  64. end;
  65.  
  66. procedure Cleanup;
  67. var
  68.   i: Integer;
  69.   AsyncFile: TAsyncFile;
  70. begin
  71.   for i := Files.Count - 1 downto 0 do
  72.   begin
  73.     AsyncFile := TAsyncFile(Files[i]);
  74.     AsyncFile.Free;
  75.   end;
  76.   Files.Free;
  77. end;
  78.  
  79. { TAsyncFile }
  80.  
  81. constructor TAsyncFile.Create(Filename: string; BufferSize: Integer);
  82. begin
  83.   Files.Add(Self);
  84.   FReadPending := False;
  85.   FBufferSize := BufferSize;
  86.   GetMem(FBuffer, FBufferSize);
  87.   FillMemory(@FOverlapped, SizeOf(FOverlapped), 0);
  88.  
  89.   Cardinal(FHandle) := CreateFile(
  90.                   PChar(Filename),         // file to open
  91.                   GENERIC_READ,            // open for reading
  92.                   0,                       // do not share
  93.                   nil,                     // default security
  94.                   OPEN_EXISTING,           // open existing
  95.                   FILE_ATTRIBUTE_NORMAL or // normal file
  96.                   FILE_FLAG_OVERLAPPED,    // asynchronous I/O
  97.                   0);                      // no attr. template
  98.  
  99.   FSize := FileSeek(FHandle, 0, soFromEnd);
  100.   FileSeek(FHandle, 0, soFromBeginning);
  101. end;
  102.  
  103. destructor TAsyncFile.Destroy;
  104. begin
  105.   Files.Remove(Self);
  106.   CloseHandle(FHandle);
  107.   FreeMem(FBuffer);
  108.   inherited;
  109. end;
  110.  
  111. function TAsyncFile.ProcessIo: Boolean;
  112. var
  113.   ReadCount: Cardinal;
  114. begin  
  115.   Result := False;
  116.   if not FReadPending then
  117.   begin
  118.     Exit;
  119.   end;
  120.  
  121.   Result := GetOverlappedResult(FHandle, FOverlapped, ReadCount, False);
  122.   if not Result then
  123.   begin
  124.     if GetLastError() = ERROR_HANDLE_EOF then
  125.     begin
  126.       FEof := True;
  127.       DoOnRead(0);
  128.     end
  129.   end
  130.   else
  131.   begin
  132.     FReadPending := False;
  133.     DoOnRead(ReadCount);
  134.   end;
  135. end;
  136.  
  137. procedure TAsyncFile.BeginRead;
  138. var
  139.   ReadResult: Boolean;
  140.   ReadCount: Cardinal;
  141. begin
  142.   ReadCount := 0;
  143.   ReadResult := ReadFile(FHandle, FBuffer^, FBufferSize, ReadCount, @FOverlapped);
  144.   if ReadResult then
  145.   begin
  146.     FEof := False;
  147.     FReadPending := False;
  148.     DoOnRead(ReadCount);
  149.   end
  150.   else
  151.   begin
  152.     case GetLastError() of
  153.       ERROR_HANDLE_EOF:
  154.       begin
  155.         FReadPending := False;
  156.         FEof := True;
  157.       end;
  158.       ERROR_IO_PENDING:
  159.       begin
  160.         FReadPending := True;
  161.       end;
  162.     end;
  163.   end;
  164. end;
  165.  
  166. procedure TAsyncFile.DoOnRead(Count: Integer);
  167. begin
  168.   if Assigned(FOnRead) then
  169.   begin
  170.     FOnRead(Self, FBuffer^, Count);
  171.   end;
  172. end;
  173.  
  174. function TAsyncFile.GetOpen: Boolean;
  175. begin
  176.   Result := Integer(FHandle) >= 0;
  177. end;
  178.  
  179. procedure TAsyncFile.Close;
  180. begin
  181.   FileClose(FHandle);
  182.   CloseHandle(FOverlapped.hEvent);
  183. end;
  184.  
  185. procedure TAsyncFile.Seek(Position: Integer);
  186. begin
  187.   FileSeek(FHandle, Position, soFromBeginning);
  188. end;
  189.  
  190. initialization
  191.   Files := Tlist.Create;
  192.  
  193. finalization
  194.   Cleanup;
  195.  
  196. end.
Add Comment
Please, Sign In to add comment