Solved

Can this functions (read inside) be done more efficient

Posted on 2002-06-01
8
151 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
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
 
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

Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

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

This article explains how to create forms/units independent of other forms/units object names in a delphi project. Have you ever created a form for user input in a Delphi project and then had the need to have that same form in a other Delphi proj…
Introduction I have seen many questions in this Delphi topic area where queries in threads are needed or suggested. I know bumped into a similar need. This article will address some of the concepts when dealing with a multithreaded delphi database…
In this video, viewers will be given step by step instructions on adjusting mouse, pointer and cursor visibility in Microsoft Windows 10. The video seeks to educate those who are struggling with the new Windows 10 Graphical User Interface. Change Cu…
NetCrunch network monitor is a highly extensive platform for network monitoring and alert generation. In this video you'll see a live demo of NetCrunch with most notable features explained in a walk-through manner. You'll also get to know the philos…
Suggested Courses
Course of the Month9 days, left to enroll

617 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