Friday, 15 June 2012

delphi - Trying to create data transfer rate calculator using Lazarus and Freepascal -



delphi - Trying to create data transfer rate calculator using Lazarus and Freepascal -

i trying add together application interface "transfer rate : xgb p\min" feature. computing @ millisecond level using lazarus 1.2.2 , freepascal 2.6.4.

i have loop reads 64kb blocks disk, stuff each 64kb block, , repeats until whole disk read or until user clicks abort button. trying time how long each read of 64kb takes , compute average rate of info read per minute, i.e. "3gb per minute".

i have custom function called 'gettimeinmilliseconds' computes standard time milliseconds.

also, avoid interface beingness refreshed ever partial millisecond, have counter tries ensure interface refreshed every 50 times round loop, i.e. when 64kb chunks have been read 50 times, counter reset 0.

the problem is, transfer display either not getting populated or gets populated inaccurate figure "234mb p\min" raid0 device! @ other times, gets more realistic "3.4gb p\min". should consistently accurate if ran repeatedly on same pc , same disk, not inconsistantly inaccurate.

here try...finally loop looping. called formatbytesize custom function computers integer size , converts xmb, xgb, xtb etc.

var progresscounter, bytestransferred, bytespersecond : integer; buffer : array [0..65535] of byte; // 65536, 64kb buffer ctx : tsha1context; digest : tsha1digest; newpos, exactdisksize, sectorcount, timestartread, timeendread, millisecondselapsed, bytespermillisecond, bytesperminute : int64; starttime, endtime, timetaken : tdatetime; ... begin ... // various stuff related handles on disks etc seek sha1init(ctx); fileseek(hselecteddisk, 0, 0); repeat progresscounter := progresscounter + 1; // utilize update progress display occasionally, instead of every buffer read timestartread := gettimeinmilliseconds(time); // starting time, in ms // hashing bit... fileread(hselecteddisk, buffer, 65536); // read 65536 = 64kb @ time newpos := newpos + sizeof(buffer); sha1update(ctx, buffer, sizeof(buffer)); fileseek(hselecteddisk, newpos, 0); lblbyteslefttohashb.caption := inttostr(exactdisksize - newpos) + ' bytes, ' + formatbytesize(exactdisksize - newpos); // end of hashing bit... timeendread := gettimeinmilliseconds(time);; // end time in ms millisecondselapsed := (timeendread - timestartread); // record how many ms's have elapsed // if loop has gone round while (50 times?), update progress display if progresscounter = 50 begin if (timestartread > 0) , (timeendread > 0) , (millisecondselapsed > 0) // divisions , computations if timings have computed positive number begin bytestransferred := sizeof(buffer); bytespermillisecond := bytestransferred div millisecondselapsed; // bytespermillisecond if reported zero, though bytestransferred , millisecondselapsed valid numbers? maybe fault? bytespersecond := bytespermillisecond * 1000; // convert bytes read per millisecond bytes read per sec bytesperminute := bytespersecond * 60; // convert bytes read per sec bytes read per min lblspeedb.caption := formatbytesize(bytesperminute) + ' p\min'; // convert big "bytes per minute" figure mb, gb or tb // reset progress counters 0 chunk of looping progresscounter := 0; bytespermillisecond := 0; bytespersecond := 0; bytesperminute := 0; progresscounter := 0; end; end; application.processmessages; until (newpos >= exactdisksize) or (stop = true); // stop looping on disk // compute final hash value sha1final(ctx, digest); lblbyteslefttohashb.caption:= '0'; // handle may have been released pressing stop. if not, handle still active lets close it. if not hselecteddisk = invalid_handle_value closehandle(hselecteddisk); endtime := now; timetaken := endtime - starttime; lblendtimeb.caption := formatdatetime('dd/mm/yy hh:mm:ss', endtime); if not stop edtcomputedhash.text := sha1print(digest); application.processmessages; ... function gettimeinmilliseconds(thetime : ttime): int64; // http://www.delphipages.com/forum/archive/index.php/t-135103.html var hour, min, sec, msec: word; begin decodetime(thetime,hour, min, sec, msec); result := (hour * 3600000) + (min * 60000) + (sec * 1000) + msec; end;

example:

form1.caption := inttostr( gettimeinmilliseconds(time) );

i sense you've made much more complicated needs be.

move file processing code separate thread. within code, finish processing bytes file, utilize interlockedadd maintain count of total number of bytes processed.

in gui thread, using timer of sort, utilize interlockedexchange read value interlockedadd has been modifying , reset zero. calculate amount of time has passed since lastly timer tick. given total number of bytes processed within elapsed time, calculate bytes per min , update gui.

since file operation on separate thread, not need worry how update gui (although doing waste of time).

if want calculate average bytes per min on entire operation, don't reset total byte counter @ each tick.

delphi freepascal lazarus tdatetime

No comments:

Post a Comment