使用文件句柄方式读 procedure PerformAsynchronousRead( const fileName : string ); var f : THandle; overlap : TOverlapped; desiredSize : DWORD; readSize : DWORD; readResult : Bool; buffer : PInteger; currentValue : PInteger; i : Integer; begin f := CreateFile( PChar(fileName), GENERIC_READ, FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, FILE_FLAG_OVERLAPPED or FILE_FLAG_NO_BUFFERING, 0 ); if f = INVALID_HANDLE_VALUE then begin WriteLn( 'Unable to open ' + fileName ); Exit; end; try // Initialize the OVERLAPPED structure FillChar(overlap, SizeOf(overlap), 0); overlap.Offset := 0; desiredSize := GetFileSize( f, nil ); buffer := VirtualAlloc( nil, desiredSize, MEM_COMMIT, PAGE_READWRITE ); try // Request the data readResult := ReadFile( f, buffer^, desiredSize, readSize, @overlap ); if readResult then WriteLn( 'Request performed as synchronous' ) else if GetLastError = ERROR_IO_PENDING then begin WriteLn( 'Request performed as ASYNCHRONOUS' ); // Do something useful here... WriteLn( 'Request queued...' ); WaitForSingleObject(f, INFINITE); WriteLn( 'Request completed.' ); readResult := GetOverlappedResult( f, overlap, readSize, False ); if not readResult then RaiseLastOSError; end else RaiseLastOSError; finally VirtualFree( buffer, desiredSize, MEM_RELEASE ); end; finally CloseHandle(f); end; end;
使用事件句柄方式 const SIMULTANEOUS_OPERATIONS = 3;procedure PerformAsynchronousRead( const fileName : string ); var f : THandle; overlaps : array[0..SIMULTANEOUS_OPERATIONS-1] of TOverlapped; events : array[0..SIMULTANEOUS_OPERATIONS-1] of THandle; desiredSize : DWORD; readSize : DWORD; readResult : Bool; buffers : array[0..SIMULTANEOUS_OPERATIONS-1] of PInteger; i : DWORD; j : Integer; value : Integer; currentValue : PInteger; begin f := CreateFile( PChar(fileName), GENERIC_READ, FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, FILE_FLAG_OVERLAPPED or FILE_FLAG_NO_BUFFERING, 0 ); if f = INVALID_HANDLE_VALUE then begin WriteLn( 'Unable to open ' + fileName ); Exit; end; try desiredSize := GetFileSize( f, nil ) div SIMULTANEOUS_OPERATIONS; for i := 0 to SIMULTANEOUS_OPERATIONS - 1 do begin events[i] := CreateEvent( nil, true, false, nil ); if events[i] = INVALID_HANDLE_VALUE then RaiseLastOSError; // Initialize the OVERLAPPED structure FillChar(overlaps[i], SizeOf(overlaps[i]), 0); overlaps[i].Offset := desiredSize * i; overlaps[i].hEvent := events[i]; buffers[i] := VirtualAlloc( nil, desiredSize, MEM_COMMIT, PAGE_READWRITE ); end; for i := 0 to SIMULTANEOUS_OPERATIONS - 1 do begin // Request the data readResult := ReadFile( f, buffers[i]^, desiredSize, readSize, @overlaps[i] ); if readResult then WriteLn( 'Request performed as synchronous' ) else begin if GetLastError = ERROR_IO_PENDING then begin WriteLn( 'Request performed as ASYNCHRONOUS' ); WriteLn( 'Request queued...' ); end else begin RaiseLastOSError; end; end; end; // Do something useful here... if WaitForMultipleObjects( SIMULTANEOUS_OPERATIONS, PWOHandleArray(@events), true, INFINITE ) = WAIT_FAILED then RaiseLastOSError; // Check result for i := 0 to SIMULTANEOUS_OPERATIONS - 1 do begin readResult := GetOverlappedResult( f, overlaps[i], readSize, False ); if not readResult then RaiseLastOSError; end; WriteLn( 'Requests completed.' ); for i := 0 to SIMULTANEOUS_OPERATIONS - 1 do begin VirtualFree( buffers[i], desiredSize, MEM_RELEASE ); CloseHandle( events[i] ); end; finally CloseHandle(f); end; end;
procedure PerformAsynchronousRead( const fileName : string );
var
f : THandle;
overlap : TOverlapped;
desiredSize : DWORD;
readSize : DWORD;
readResult : Bool;
buffer : PInteger;
currentValue : PInteger;
i : Integer;
begin
f := CreateFile( PChar(fileName),
GENERIC_READ, FILE_SHARE_READ or FILE_SHARE_WRITE,
nil, OPEN_EXISTING,
FILE_FLAG_OVERLAPPED or FILE_FLAG_NO_BUFFERING, 0 );
if f = INVALID_HANDLE_VALUE then begin
WriteLn( 'Unable to open ' + fileName );
Exit;
end;
try
// Initialize the OVERLAPPED structure
FillChar(overlap, SizeOf(overlap), 0);
overlap.Offset := 0; desiredSize := GetFileSize( f, nil );
buffer := VirtualAlloc( nil, desiredSize, MEM_COMMIT, PAGE_READWRITE );
try
// Request the data
readResult := ReadFile( f, buffer^, desiredSize, readSize, @overlap );
if readResult then
WriteLn( 'Request performed as synchronous' )
else if GetLastError = ERROR_IO_PENDING then begin
WriteLn( 'Request performed as ASYNCHRONOUS' );
// Do something useful here...
WriteLn( 'Request queued...' );
WaitForSingleObject(f, INFINITE);
WriteLn( 'Request completed.' ); readResult := GetOverlappedResult( f, overlap, readSize, False );
if not readResult then
RaiseLastOSError;
end
else
RaiseLastOSError;
finally
VirtualFree( buffer, desiredSize, MEM_RELEASE );
end;
finally
CloseHandle(f);
end;
end;
const
SIMULTANEOUS_OPERATIONS = 3;procedure PerformAsynchronousRead( const fileName : string );
var
f : THandle;
overlaps : array[0..SIMULTANEOUS_OPERATIONS-1] of TOverlapped;
events : array[0..SIMULTANEOUS_OPERATIONS-1] of THandle;
desiredSize : DWORD;
readSize : DWORD;
readResult : Bool;
buffers : array[0..SIMULTANEOUS_OPERATIONS-1] of PInteger;
i : DWORD;
j : Integer;
value : Integer;
currentValue : PInteger;
begin
f := CreateFile( PChar(fileName),
GENERIC_READ, FILE_SHARE_READ or FILE_SHARE_WRITE,
nil, OPEN_EXISTING,
FILE_FLAG_OVERLAPPED or FILE_FLAG_NO_BUFFERING, 0 );
if f = INVALID_HANDLE_VALUE then begin
WriteLn( 'Unable to open ' + fileName );
Exit;
end;
try
desiredSize := GetFileSize( f, nil ) div SIMULTANEOUS_OPERATIONS; for i := 0 to SIMULTANEOUS_OPERATIONS - 1 do begin
events[i] := CreateEvent( nil, true, false, nil );
if events[i] = INVALID_HANDLE_VALUE then
RaiseLastOSError;
// Initialize the OVERLAPPED structure
FillChar(overlaps[i], SizeOf(overlaps[i]), 0);
overlaps[i].Offset := desiredSize * i;
overlaps[i].hEvent := events[i]; buffers[i] := VirtualAlloc( nil, desiredSize, MEM_COMMIT, PAGE_READWRITE );
end; for i := 0 to SIMULTANEOUS_OPERATIONS - 1 do begin
// Request the data
readResult := ReadFile( f, buffers[i]^, desiredSize, readSize, @overlaps[i] );
if readResult then
WriteLn( 'Request performed as synchronous' )
else begin
if GetLastError = ERROR_IO_PENDING then begin
WriteLn( 'Request performed as ASYNCHRONOUS' );
WriteLn( 'Request queued...' );
end
else begin
RaiseLastOSError;
end;
end;
end; // Do something useful here...
if WaitForMultipleObjects( SIMULTANEOUS_OPERATIONS,
PWOHandleArray(@events), true, INFINITE ) =
WAIT_FAILED then
RaiseLastOSError; // Check result
for i := 0 to SIMULTANEOUS_OPERATIONS - 1 do begin
readResult := GetOverlappedResult( f, overlaps[i], readSize, False );
if not readResult then
RaiseLastOSError;
end; WriteLn( 'Requests completed.' ); for i := 0 to SIMULTANEOUS_OPERATIONS - 1 do begin
VirtualFree( buffers[i], desiredSize, MEM_RELEASE );
CloseHandle( events[i] );
end;
finally
CloseHandle(f);
end;
end;