How to add increasing number to saved files in Delphi?
Question
I'm making a program that takes a snapshot of the screen, and saves it to a folder as a Bitmap picture. I seem to be running into a problem though, the picture just overwrites itself.
Can anyone tell me how I can make it so when it saves, the number will be one higher than the last? For example: Save 1: Screenshot0001.bmp Save 2: Screenshot0002.bmp Save 3: Screenshot0003.bmp
And so on.
Solution
There are many ways to accomplish something like this.
Do it like your digital camera does; Have a counter and save it in a file or in the registry. You'll probably run into multi-user problems and you'll still have to handle situations where an image already exists.
Don't use a incrementing number, but write a datetime in the filename. FileName := 'Screenshot_'+FormatDateTime('yyyymmdd-hhnnss-zzz.bmp',now());
Do something like the code below to find the latest number. I think this does what you're describing, but remember that this code will get slower as you write more images. With thousands of pictures and a slow drive or network it could 'hang' your program.
..
i := 0;
while FileExists(Format('%sScreenshot%.04d.bmp',[ImgPath,i])) do
inc(i);
OTHER TIPS
At program startup, iterate all Screenshot*.bmp files, parse out the numeric part and find the highest - assign this value to your counter. When doing a snapshot, go into a loop that tries crreating Screenshot.bmp with "only create if doesn't exist already" (CREATE_NEW) semantics, incrementing the counter until you find an unused name.
Alternately, use timestamp instead of counter :)
You need a routine like this which mimics Windows file duplication where the first file is 'My File', the second is 'My File (2)', then 'My File (3)' etc.
function AppendDuplicationNumber( const AStr : string ) : string;
// Used to make strings unique
// This examines the string AStr for trailing '(n)' where
// 'n' is an integer.
// If the (n) part is found, n is incremented, otherwise '(2)' is
// appended to the string.
var
iLH, iRH, I : integer;
S : string;
begin
Result := AStr;
iLH := CharPosBackwards( '(', Result );
If iLH > 0 then
begin
iRH := PosEx( ')', Result, iLH );
If iRH > 0 then
begin
I := StrToIntDef( Copy( Result, iLH+1, iRH-iLH-1 ), 0 );
If I > 0 then
begin
Inc(I);
S := IntToStr( I );
Delete( Result, iLH+1, iRH-iLH-1 );
Insert( S, Result, iLH+1 );
Exit;
end;
end;
end;
// Did not increment existing (n), so append it.
Result := Result + ' (2)';
end;