program readfile; {$mode objfpc}{$H+} uses {$IFDEF UNIX}{$IFDEF UseCThreads} cthreads, {$ENDIF}{$ENDIF} Classes, SysUtils, CustApp, windows { you can add units after this }; type { readfile } rfile = class(TCustomApplication) protected procedure DoRun; override; public constructor Create(TheOwner: TComponent); override; destructor Destroy; override; procedure WriteHelp; virtual; end; { rfile } procedure rfile.DoRun; var ErrorMsg, FileName: String; //Fin : File; Fin : THANDLE; NumRead, PrevNumRead, NumOverlapped : LongWord; Buf : Array of Byte; BufSize, NumReadOps, StartTime, EndTime, ExecTime, Size: Int64; Speed : Double; fsizehigh, fsizelow: DWORD; begin // quick check parameters ErrorMsg:=CheckOptions('h','help'); if ErrorMsg<>'' then begin ShowException(Exception.Create(ErrorMsg)); Terminate; Exit; end; // parse parameters if HasOption('h','help') then begin WriteHelp; Terminate; Exit; end; If Paramcount < 1 then WriteHelp; FileName := ParamStr(1); If ParamCount > 1 then BufSize := StrToInt(ParamStr(2)) else BufSize := 4096; NumRead := 0; SetLength(Buf, BufSize); Bufsize := Length(Buf); NumReadOps:=0; // Number of read operations If FileExists (FileName) then begin //System.Assign (Fin, FileName); //Fin := windows.CreateFile(PChar(FileName),FILE_FLAG_NO_BUFFERING, 0, LPSECURITY_ATTRIBUTES,OPEN_EXISTING, 0, 0); Fin := CreateFile( PChar(FileName), GENERIC_READ, 0, NIL, OPEN_EXISTING, FILE_FLAG_NO_BUFFERING, 0); if (Fin = INVALID_HANDLE_VALUE) then Exit; fsizelow := Windows.GetFileSize(Fin, Pointer(@fsizehigh)); //Reset (Fin,1); WriteLn('Reading "',FileName,'"'); //WriteLn('FileSize: ',FileSize(Fin), ' bytes'); WriteLn('FileSizeHigh: ',fsizehigh, ' bytes'); WriteLn('FileSizeLow: ',fsizelow, ' bytes'); WriteLn('Bufsize:', bufsize); StartTime := Windows.GetTickCount(); Repeat PrevNumRead := NumRead; //BlockRead (Fin,buf[0],BufSize,NumRead); Windows.ReadFile(Fin, Buf[0], BufSize, NumRead, @NumOverlapped); inc(NumReadOps); //If NumReadOps mod 100000 = 0 then // writeln(Total, ' : ', NumReadOps * BufSize); Until (NumRead=0); //close(Fin); Windows.CloseHandle(Fin); EndTime := Windows.GetTickCount(); // Add 1 in order to avoid divbyzero on very short exectime ExecTime:= EndTime - StartTime + 1; WriteLn(); //WriteLn('Numread=',NumRead); //WriteLn('PrevNumRead=',PrevNumRead); //writeln(NumReadOps, ' : ', NumReadOps * BufSize); Size := (NumReadOps-2) * BufSize + PrevNumRead; If Size < 0 then Size := 0; Speed := Size / ExecTime; WriteLn ('Read ',Size, ' bytes (', FloatToStrF(Size/1024/1024, ffFixed,1,1), ' mb) from file ',FileName, ' in ', ExecTime, ' ms :'); Speed := Size / (ExecTime/1000); WriteLn(FloatToStrF(speed,ffFixed,1,2), ' b/s'); WriteLn(FloatToStrF(speed/1024,ffFixed,1,2), ' kb/s'); WriteLn(FloatToStrF(speed/1024/1024,ffFixed,1,2), ' mb/s'); WriteLn(FloatToStrF(speed/1024/1024/1024,ffFixed,1,2), ' gb/s'); end else begin Writeln ('File "'+FileName+'" NOT found'); end; //Write('Enter to quit'); //ReadLn; // stop program loop Terminate; end; constructor rfile.Create(TheOwner: TComponent); begin inherited Create(TheOwner); StopOnException:=True; end; destructor rfile.Destroy; begin inherited Destroy; end; procedure rfile.WriteHelp; begin WriteLn('Usage: '+ExeName+' [bufsize]'); WriteLn(' Default bufsize: 4096'); WriteLn(''); WriteLn('Example: ', ExeName, ' c:\tempfile.dat 1024'); Halt; end; var Application: rfile; {$R *.res} begin Application:=rfile.Create(nil); Application.Title:='rfile'; Application.Run; Application.Free; end.