Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations biv343 on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

renaming files based on extension

Status
Not open for further replies.

CADTenchy

Technical User
Dec 12, 2007
237
GB
before I go down a wrong path, thought I'd check in case there was a blindingly easy way to do my thing..

I'm using the proc at bottom to find all the files contained in a directory.
Once I have that, I want to look through the list and find all those that have an extension matching a lookup list.
Those that do, I want to add to a listbox.items set, and at the same index in another listbox.items set I want to add that same file name, with extra text before the extension, depending on which extension it is.
Those files in the search list that do not match any of the lookup extensions are to be put into a 3rd list.

As so:
lookup table:
abc fred
efg john
ghi bob


Search.list New1.list new2.list new3.list
file1.abc file1.abc file1 fred.abc file3.tar
file2.efg file2.efg file2 john.efg file4.uue
file3.tar file5.ghi file5 bob.ghi
file4.uue file6.abc file6 fred.abc
file5.ghi
file6.abc

Are there built in functions I can use for this seemingly simple task?

Steve

Search proc:


//this proc finds all files in a directory passed to it
procedure ListFileDir(Path: String; FileList: TStrings);

var
SR: TSearchRec;

begin
if FindFirst(Path + '*.*', faAnyFile, SR) = 0 then
begin
repeat
if (SR.Attr And faDirectory) <> faDirectory then
begin
FileList.Add(SR.Name);
end;
until FindNext(SR) <> 0;
FindClose(SR);
end;
end;


 
This sounds a lot like a homework question, so I won't be posting finished code - however I'm happy to give you a starting push.

Start with your ListFileDir procedure, but get rid of the FileList parameter, and instead add new code where you have FileList.Add(SR.Name). This is a good point to decide which list each file will be added to.

The ExtractFileExt function will give you the extension for each file - you'll need to strip of the leading full stop though before you make comparisons, or add a full stop to your lookup list items. If your lookup list exists in a TStringList, consider making the entries of the form abc=fred, that way you can use the TStringList.Values property to quickly find entries.

To Insert your lookup value into the filename for list2, I'd use code similar to
Code:
List2.Add(Copy(SR.Name, 1, Length(SR.Name) - Length(ExtractFileExt(SR.Name))) + LookupValue + ExtractFileExt(SR.Name));

You could make use of the Insert procedure for neater code if you like.

The rest seems to be a loop and an if..else

Post back if you have any more troubles.
 
Hi Grifin,

Thanks for that. The most sensible thing you said was to do the processing in the reading routine itself. Doh! Thanks again.
I'm coming back to Delphi from a break since Delphi 3 was new, so I'm stretching the worn out memory cells a tad. Back then I was no expert, but I did have a better handle on what Delphi needed to work...

Anyway,I've played around (resisting the fairly strong urge to seek more help!) with a new routine based on one above, re-learning about declaring procedures and global variables, and have now got it to a state where I can start on the actual logic & decision making part.(In other words the bit I have got works now!)

Be in touch...

Steve
 
Ok, I have decent progess, but an unexpected fault, which I think is down to spaces in the filename not being catered for.

First I load the LookUpData on formcreate:
Code:
procedure TSDIAppForm.FormCreate(Sender: TObject);
begin
  LookUpData :=  TStringList.Create;
  LookUpData.LoadFromFile('extensions.txt');
end;

Q: Do I need a closefile command here of any sort?

Moving on to main proc...

I have 3 Tlistbox's to display how it's working etc:

SourceBox for original contents of the folder
OutBox for list of files as they will be renamed
KillBox for list of files to delete

Everything works well except for an issue I think is to do with filenames with spaces in them, into which I am looking.

So assuming filenames with no spaces, can you see improvements in my code?

Code:
procedure TSDIAppForm.FillListBoxes;
var
  SR: TSearchRec;
  i: integer;   //for for-to loop

begin
  Outbox.Items.Clear;  
  KillBox.Items.Clear; 
  Sourcebox.Items.Clear;

  if FindFirst(Dir + '*.*', faAnyFile, SR) = 0 then
  begin
    repeat
      if (SR.Attr And faDirectory) <> faDirectory then  //exclude directories
      begin
        SourceBox.Items.Add(SR.Name);
        for i := 0 to LookUpData.Count - 1 do
          if LookUpData.Names[i] = ExtractFileExt(SR.Name) then
             begin
               if LookUpData.ValueFromIndex[i] = 'delete' then
               KillBox.Items.Add(SR.Name) else           
               Outbox.Items.Add(Copy(SR.Name, 1, Length(SR.Name) - Length(ExtractFileExt(SR.Name))) + LookUpData.ValueFromIndex[i] + ExtractFileExt(SR.Name));
             end;
      end;
    until FindNext(SR) <> 0;
    FindClose(SR);
  end;

end;
 
Q: Do I need a closefile command here of any sort?

No.

So assuming filenames with no spaces, can you see improvements in my code?

I'm not sure I understand your complete requirement, but the issue I would have with the code as presented is one of clarity and efficiency. Remember that any function call has an associated overhead and you will have that overhead for each and every call. Then having multiple repeated function calls lowers the clarity of the code.

Perhaps something like this (untested):
Code:
for i := 0 to LookUpData.Count - 1 do
  begin
    fileext := ExtractfileExt(Sr.Name);
    if LookUpData.Names[i] = fileext then
       begin
         if LookUpData.ValueFromIndex[i] = 'delete' then
            KillBox.Items.Add(SR.Name) 
         else           
            Outbox.Items.Add(Copy(SR.Name, 1, Length(SR.Name) - Length(fileext)) + LookUpData.ValueFromIndex[i] + fileext);
       end;
  end;

If inserting the lookupdata value between the first part of the name and the extension, I'd consider simply counting from the length of the file name backwards until I hit a period and then use that instead of "Length(Sr.name) - Length(fileext)". I don't know how well ExtractFileExt works in file names with spaces (not well, perhaps, I seem to remember having a go-round with this problem once before). But I would suggest this method over ExtractFileExt to deal with your spaces problem in the file names.
 
Hi Glen,
You have a valid point. The proc will grow to actually achieve it's aim, so defining a variable to contain the extension etc is good idea.
Thanks.
Steve
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top