Solved

Can this functions (read inside) be done more efficient

Posted on 2002-06-01
8
145 Views
Last Modified: 2010-04-04
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
Comment
Question by:joyrider
  • 3
  • 2
  • 2
  • +1
8 Comments
 
LVL 1

Expert Comment

by:RHuebner
ID: 7049112
Use a hidden index file in the directory, much like what you might find in the cookies directory.

Good Luck,
RH.
0
 
LVL 12

Expert Comment

by:Lee_Nover
ID: 7049493
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
 

Author Comment

by:joyrider
ID: 7049506
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
 
LVL 1

Expert Comment

by:Fraction
ID: 7049526
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
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 
LVL 1

Expert Comment

by:Fraction
ID: 7049529
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
 
LVL 12

Accepted Solution

by:
Lee_Nover earned 75 total points
ID: 7049550
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
 

Author Comment

by:joyrider
ID: 7049674
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
 
LVL 1

Expert Comment

by:Fraction
ID: 7049949
Wow, didn't know there was a disk-notification.
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

The uses clause is one of those things that just tends to grow and grow. Most of the time this is in the main form, as it's from this form that all others are called. If you have a big application (including many forms), the uses clause in the in…
Hello everybody This Article will show you how to validate number with TEdit control, What's the TEdit control? TEdit is a standard Windows edit control on a form, it allows to user to write, read and copy/paste single line of text. Usua…
This Micro Tutorial demonstrates using Microsoft Excel pivot tables, how to reverse engineer competitors' marketing strategies through backlinks.
Many functions in Excel can make decisions. The most simple of these is the IF function: it returns a value depending on whether a condition you describe is true or false. Once you get the hang of using the IF function, you will find it easier to us…

912 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

24 Experts available now in Live!

Get 1:1 Help Now