在此article delphi.net(棱鏡)支持異步文件IO O操作。 德爾福(本機/ VCL)也有異步文件IO類?異步文件I /德爾福
回答
你見過這個代碼嗎? http://pastebin.com/A2EERtyW
這對於異步文件I/O是一個很好的開始,但是我個人會在標準的TStream
類中編寫一個包裝來維護與VCL/RTL的兼容性。
編輯2:這一個看起來很不錯了。 http://www.torry.net/vcl/filedrv/other/dstreams.zip
我只是萬一在這裏張貼從引擎收錄消失:
unit xfile;
{$I cubix.inc}
interface
uses
Windows,
Messages,
WinSock,
SysUtils,
Classes;
const
MAX_BUFFER = 1024 * 32;
type
TFileReadEvent = procedure(Sender: TObject; const Buffer; Count: Integer) of object;
TAsyncFile = class
private
FHandle: THandle;
FPosition: Cardinal;
FReadPending: Boolean;
FOverlapped: TOverlapped;
FBuffer: Pointer;
FBufferSize: Integer;
FOnRead: TFileReadEvent;
FEof: Boolean;
FSize: Integer;
function ProcessIo: Boolean;
procedure DoOnRead(Count: Integer);
function GetOpen: Boolean;
public
constructor Create(Filename: string; BufferSize: Integer = MAX_BUFFER);
destructor Destroy; override;
procedure BeginRead;
procedure Seek(Position: Integer);
procedure Close;
property OnRead: TFileReadEvent read FOnRead write FOnRead;
property Eof: Boolean read FEof;
property IsOpen: Boolean read GetOpen;
property Size: Integer read FSize;
end;
function ProcessFiles: Boolean;
implementation
var
Files: TList;
function ProcessFiles: Boolean;
var
i: Integer;
AsyncFile: TAsyncFile;
begin
Result := False;
for i := Files.Count - 1 downto 0 do
begin
AsyncFile := TAsyncFile(Files[i]);
Result := AsyncFile.ProcessIo or Result;
end;
end;
procedure Cleanup;
var
i: Integer;
AsyncFile: TAsyncFile;
begin
for i := Files.Count - 1 downto 0 do
begin
AsyncFile := TAsyncFile(Files[i]);
AsyncFile.Free;
end;
Files.Free;
end;
{ TAsyncFile }
constructor TAsyncFile.Create(Filename: string; BufferSize: Integer);
begin
Files.Add(Self);
FReadPending := False;
FBufferSize := BufferSize;
GetMem(FBuffer, FBufferSize);
FillMemory(@FOverlapped, SizeOf(FOverlapped), 0);
Cardinal(FHandle) := CreateFile(
PChar(Filename), // file to open
GENERIC_READ, // open for reading
0, // do not share
nil, // default security
OPEN_EXISTING, // open existing
FILE_ATTRIBUTE_NORMAL, //or // normal file
//FILE_FLAG_OVERLAPPED, // asynchronous I/O
0); // no attr. template
FSize := FileSeek(FHandle, 0, soFromEnd);
FileSeek(FHandle, 0, soFromBeginning);
FPosition := 0;
end;
destructor TAsyncFile.Destroy;
begin
Files.Remove(Self);
CloseHandle(FHandle);
FreeMem(FBuffer);
inherited;
end;
function TAsyncFile.ProcessIo: Boolean;
var
ReadCount: Cardinal;
begin
Result := False; Exit;
if not FReadPending then
begin
Exit;
end;
if GetOverlappedResult(FHandle, FOverlapped, ReadCount, False) then
begin
FReadPending := False;
DoOnRead(ReadCount);
end
else
begin
case GetLastError() of
ERROR_HANDLE_EOF:
begin
FReadPending := False;
FEof := True;
end;
ERROR_IO_PENDING:
begin
FReadPending := True;
end;
0:
begin
Result := True;
end;
end;
end;
end;
procedure TAsyncFile.BeginRead;
var
ReadResult: Boolean;
ReadCount: Cardinal;
begin
ReadCount := 0;
Seek(FPosition);
ReadResult := ReadFile(FHandle, FBuffer^, FBufferSize, ReadCount, nil);//@FOverlapped);
if ReadResult then
begin
FEof := False;
FReadPending := False;
FPosition := FPosition + ReadCount;
DoOnRead(ReadCount);
end
else
begin
case GetLastError() of
ERROR_HANDLE_EOF:
begin
FReadPending := False;
FEof := True;
end;
ERROR_IO_PENDING:
begin
FReadPending := True;
end;
end;
end;
end;
procedure TAsyncFile.DoOnRead(Count: Integer);
begin
if Assigned(FOnRead) then
begin
FOnRead(Self, FBuffer^, Count);
end;
end;
function TAsyncFile.GetOpen: Boolean;
begin
Result := Integer(FHandle) >= 0;
end;
procedure TAsyncFile.Close;
begin
FileClose(FHandle);
end;
procedure TAsyncFile.Seek(Position: Integer);
begin
FPosition := Position;
FileSeek(FHandle, Position, soFromBeginning);
end;
initialization
Files := Tlist.Create;
finalization
Cleanup;
end.
異步IO功能是隱藏的(評論)在此代碼 – MajidTaheri
然後看看第二個代碼。 – Pateman
在上面的文章是基於事件(ReadDone功能),但DSTREAM不是基於事件的,讀取和ReadAsync的參數是相同 – MajidTaheri
沒有什麼內置在RTL/VCL對於文件提供了異步I/O。順便提一下,Delphi Prism中的支持取決於.net框架,而不是基於語言。
您可以代碼直接對抗的Win32 API(這是不是很有趣),或到處尋找一個Delphi包裝該API。關於我的頭頂,我不知道任何異步文件I/O的Delphi包裝,但它們必須存在。
- 1. 德爾福Tstringlist,寫文件同步
- 2. 德爾福REST請求異步
- 3. 異步追加到德爾福的.txt文件
- 4. 德爾福HID Delphi7和德爾福XE2
- 5. 德爾福7德爾福XE2 res文件問題
- 6. 德爾福TPair異常
- 7. 德爾福6 - >德爾福2006年dbexpress怪異?
- 8. MQ(從i系列)和德爾福
- 9. 與德爾福
- 10. 德爾福的inc(i)和i:= i + 1之間有性能差異嗎?
- 11. 德爾福v.Word - 如何從德爾福
- 12. 德爾福ftpgetfile
- 13. 德爾福
- 14. 解析德爾福
- 15. 德爾福:TImage中
- 16. 德爾福
- 17. 與德爾福
- 18. 寫入德爾福
- 19. 德爾福保存到文本文件
- 20. 德爾福:TRegExpr
- 21. 類德爾福
- 22. 德爾福
- 23. DES_KEY_SZ德爾福
- 24. 德爾福
- 25. 與德爾福
- 26. 德爾福Application.HintColor
- 27. 德爾福XE2(優勢德爾福組件)
- 28. 德爾福結構
- 29. 德爾福與流
- 30. 德爾福 - 素數
對於VC++有這個可能很容易地移植到德爾福:http://www.codeproject.com/Articles/174595/A-Simple-Wrapper for Asynchronous-File-IO-ReadFil - 但我的問題是爲什麼要麻煩。原始的Win32 API並不難處理,你需要一個類包裝器。 –
相關/相關:http://stackoverflow.com/questions/2953070/the-most-elegant-way-to-encapsulate-winapi-callbacks-inside-a-class –