Как увеличить число сохраненных файлов в Delphi?

Я делаю программу, которая делает снимок экрана и сохраняет его в папку в виде растрового изображения. Кажется, у меня возникла проблема, изображение просто перезаписывает себя.

Может ли кто-нибудь сказать мне, как я могу сделать так, чтобы при сохранении число было на единицу больше, чем последнее? Например: Сохранить 1: Screenshot0001.bmp Сохранить 2: Screenshot0002.bmp Сохранить 3: Screenshot0003.bmp

И так далее.


person PuppyKevin    schedule 17.03.2009    source источник


Ответы (3)


Есть много способов добиться чего-то подобного.

  1. Сделайте это, как ваша цифровая камера; Заведите счетчик и сохраните его в файл или в реестр. Вы, вероятно, столкнетесь с проблемами, связанными с несколькими пользователями, и вам все равно придется справляться с ситуациями, когда образ уже существует.

  2. Не используйте увеличивающееся число, а напишите дату и время в имени файла. FileName := 'Screenshot_'+FormatDateTime('yyyymmdd-hhnnss-zzz.bmp',now());

  3. Сделайте что-то вроде кода ниже, чтобы найти последний номер. Я думаю, что это делает то, что вы описываете, но помните, что этот код будет работать медленнее по мере того, как вы будете писать больше изображений. С тысячами изображений и медленным диском или сетью это может «подвесить» вашу программу.

..

i := 0;
while FileExists(Format('%sScreenshot%.04d.bmp',[ImgPath,i])) do
  inc(i);
person Wouter van Nifterick    schedule 17.03.2009
comment
У меня проблема. Я добавил FileName := +FormatDateTime('yyyymmdd-hhnnss-zzz.bmp',now()); и добавил [FileName] к следующему коду: bmp.SaveToFile('C:\Screenshots\ScreenShot[FileName].bmp'); Но я не знаю, правильно ли я делаю. FileName:= говорит, что он не объявлен. - person PuppyKevin; 17.03.2009
comment
Тебе нужно объявить свои переменные, Кевин. Проверьте справку об этом. Также проверьте справку о конкатенации строк. - person Rob Kennedy; 17.03.2009
comment
Я объявил переменную FileName как FileName: string;, я переписал строки FileName := и SaveTo как: FileName := 'Screenshot_'+FormatDateTime('yyyymmdd-hhnnss-zzz',now()); bmp.SaveToFile('C:\Screenshots[FileName].bmp'); и теперь, когда он создает и сохраняет Bitmap, он выходит как [FileName].bmp. - person PuppyKevin; 17.03.2009
comment
@PuppyKevin: попробуйте bmp.SaveToFile('C:\Screenshots\' + FileName + '.bmp'); вместо этого или используйте другой вызов Format(): bmp.SaveToFile(Format('C:\Screenshots\%s.bmp', [FileName])); - person mghie; 17.03.2009
comment
Mghie, я использовал ваш способ Format(), и это сработало! Спасибо всем за помощь мне :) - person PuppyKevin; 17.03.2009

При запуске программы переберите все файлы Screenshot*.bmp, выделите числовую часть и найдите наибольшую - присвойте это значение своему счетчику. При создании моментального снимка войдите в цикл, который пытается создать Screenshot.bmp с семантикой «создавать только, если он еще не существует» (CREATE_NEW), увеличивая счетчик до тех пор, пока не найдете неиспользуемое имя.

В качестве альтернативы используйте метку времени вместо счетчика :)

person snemarch    schedule 17.03.2009
comment
+1 за совет сделать это атомарно (удобно для нескольких пользователей). Но, учитывая уровень опыта ОП, другой ответ кажется более подходящим. - person mghie; 17.03.2009

Вам нужна подобная процедура, которая имитирует дублирование файлов Windows, где первый файл — «Мой файл», второй — «Мой файл (2)», затем «Мой файл (3)» и т. д.

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;
person Brian Frost    schedule 17.03.2009
comment
Это явно не то, что имел в виду ОП, он специально хочет имена файлов, одна часть которых представляет собой увеличивающееся число. - person mghie; 17.03.2009