Go Premium for a chance to win a PS4. Enter to Win

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 154
  • Last Modified:

Can this functions (read inside) be done more efficient

Hi there,


i'm making some kind of screenshot convertor, the program can copies the converted files in a separate dir in the form of shotXXXXX.jpg wher XXXXX are nrs (for example shot00001.jpg) now i made a little function to know what the next filename should be and it works like this :

i got a counter (longint) wich start from zero (0)
then it makes the filename like dir + 'shot' + counter (if counter is not 5 place great for example 1 it makes 00001 of it) then it adds .jpg and checks if the filename exists if it does'nt it returns the filename if it does it starts again with the teller increased by one

it works perfect but imagine i got 1000 jpg files (shot00000.jpg to shot09999.jpg) to find the next filename
it will iterate a 1000 times and checks if the file exists

obviously this slows things down and i wonder if there's a faster and better way to do it also i want the function to return the first availible filename so if shot00100.jpg was deleted it should return that filename (function already does it now, that's what makes it difficult for me)
if it didn't need to do it i could just make the counter never loose its value so i can start from there, but that's not an option since it has to use the deleted filenames also !


here's the function i made :

function getNextFileName(dir: string;extension : string):string;
var
 teller : longint;
 tel : integer;
 filename : string;
begin
 teller := 0;
 filename := dir + '\shot';
 for tel := 1 to (5 - length(inttostr(teller))) do filename := filename + '0';
 filename := filename + inttostr(teller)+extension;
 while fileexists(filename)do
 begin
  teller := teller +1;
  filename := dir + '\shot';
  for tel := 1 to (5 - length(inttostr(teller))) do filename := filename + '0';
  filename := filename + inttostr(teller)+extension;
 end;
 getNextFileName := filename;
end;


any idea's ?
0
joyrider
Asked:
joyrider
  • 3
  • 2
  • 2
  • +1
1 Solution
 
RHuebnerCommented:
Use a hidden index file in the directory, much like what you might find in the cookies directory.

Good Luck,
RH.
0
 
Lee_NoverCommented:
an index file is a good idea
whenever you run your application you should update that index file
so you'll know all the deleted files

you could have something like this in an ini file :

[Indexes]
LastIndex=100

[DeletedIndexes]
34=0
58=0
93=0


so you first check the DeletedIndexes section for any entries
if there are any then take the first Index for your file
otherwise use the one from LastIndex
it should be simple enough :)
0
 
joyriderAuthor Commented:
yes that could work except the program runs in the system tray so it could be they(users) deleted files even when the program was running so i would still need to recreate an index file whenever i need the function to be sure that the index file is 100% up to date :(

i did however manage to get it working somewhat faster by using a windows 3.1 filelistbox + checking if the nr of files matches the last filename (if so no files where deleted) and i know next filename immediatly

now this works great but isn't there some function so i would get the same results as with the filelistbox but an ivisible control (so it would return the stringslist only and don't draw anything on screen (i got it set to invisible doh))
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
FractionCommented:
Maybe the FileExists() scan your dir everytime you check if the filename exists. It may be faster if you just scan it once, try this:

function TForm1.getNextFileName(dir: string;extension : string):string;
const
  FStart: string = 'shot';
var
  sr: TSearchRec;
  List: TStringList;
  i: integer;
  FEnd: string[5];
begin

  List := TStringList.Create; // First Scan the dir
  i := FindFirst(Format('%s\%s*.%s', [dir, FStart, extension]), faAnyFile, sr); // Note the mask (shot*.jpg)
  while i=0 do begin
    List.Add(Lowercase(sr.Name)); // all lowercase (just in case)
    i := FindNext(sr);
  end;
  FindClose(sr);

  i := 0; // start with 0;
  repeat
    FEnd := IntToStr(i);
    while length(FEnd)<5 do FEnd := '0' + FEnd; // Fill 0 to the left
  until List.IndexOf(Lowercase(Format('%s%s.%s', [FStart, FEnd, extension]))) < 0;

  List.Free; // if you're done, free the list

  result := Format('%s%s.%s', [FStart, FEnd, extension]);
end;

0
 
FractionCommented:
Sorry!
Change the repeat until block to this:

 repeat
   FEnd := IntToStr(i);
   while length(FEnd)<5 do FEnd := '0' + FEnd; // Fill 0 to the left
    inc(i); // increse i!!!!!!
 until List.IndexOf(Lowercase(Format('%s%s.%s', [FStart, FEnd, extension]))) < 0;
0
 
Lee_NoverCommented:
you could also install a disk monitor :)
you can use rxLibs DiskMonitor .. one is supplied with D6
or you can call the FindFirstChangeNotification function manually :)
so everytime you get a file deletion you correct the index file :)
0
 
joyriderAuthor Commented:
fraction i tried your way it is faster as my first function but it's slower then the addition i made described in my 2nd post i think the notification of changes will do the trick just fine while keeping an index file

thanks
0
 
FractionCommented:
Wow, didn't know there was a disk-notification.
0

Featured Post

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

  • 3
  • 2
  • 2
  • +1
Tackle projects and never again get stuck behind a technical roadblock.
Join Now