Board index » delphi » ALL recursive subdirectories

ALL recursive subdirectories

These bits are what I am using at the moment but it only goes 2
subdirectories deeper than the one it starts off at how do I make it go to
recursive subdirectories and once I have a list of all the files and there
sizes how do I sort them by size (cant use an array dont know how big it
should be)
TIA

Procedure BuildList(Path : PathStr);
Begin
     ChDir(Path);
     FindFirst('*.*', Anyfile, MP3Search);
     While DosError = 0 do
       Begin
         If MP3Search.Attr<>Directory Then
           Begin
             MP3mem.Name:=Path+MP3Search.Name;
             MP3mem.Size:=MP3Search.Size;
             Write(MP3file,MP3mem);
           End;
         FindNext(MP3Search);
       End;
End;

Procedure BuildDIR(Path : PathStr);
Var SUBDIRSearch : SearchRec;
Begin
     ChDir(Path);
     FindFirst('*.*', Directory, SUBDIRSearch);
     Append(DIRfile);
     While DosError = 0 do
       Begin
         If (SUBDIRSearch.Attr=Directory) and (SUBDIRSearch.name<>'.') and
(SUBDIRSearch.name<>'..') Then
           Writeln(DIRfile,FExpand(Path)+SUBDIRSearch.Name+'\');
         FindNext(SUBDIRSearch);
       End;
     Close(DIRfile);
End;

     Rewrite(DIRfile);
     Writeln(DIRfile,INDIR);
     Close(DIRfile);
     FindFirst(INDIR+'*.*', Directory, DIRSearch);
     While DosError = 0 do
       Begin
         If (DIRSearch.Attr and Directory>0) and
         (DIRSearch.name<>'.') and (DIRSearch.name<>'..') Then
         BuildDIR(INDIR+DIRSearch.name+'\');
         FindNext(DIRSearch);
       End;
     Rewrite(MP3file);
     BuildDIR(INDIR);
     Reset(DIRfile);
     While Not EOF(DIRFile) do
       Begin
         Readln(DIRFile,DIRmem);
         BuildList(DIRmem);
       End;
     Close(DIRFile);
     Erase(DIRFile);

 

Re:ALL recursive subdirectories


Hi,

on Fri, 14 Jan 2000 at 07:57:31 o'clock, Keza wrote:

Quote
> These bits are what I am using at the moment but it only goes 2
> subdirectories deeper than the one it starts off at how do I make it go to
> recursive subdirectories

  ^^^^^^^^^

Recursively. Please see <http://www.bastisoft.de/pascal/sources/fulldir.pas>.

Quote
> and once I have a list of all the files and there
> sizes how do I sort them by size (cant use an array dont know how big it
> should be)

An old DOS trick to sort a dir listing by size is:

   dir c: | sort /+14 /R

You should check, however, if column 14 is where the size starts in your
DOS version / in your file (if you write the file, take the freedom to
start every line with the size).

In case you really want to sort the entries yourself, you should use a
linked list instead of an array. There are also ways to sort entries in
files, but if you're going to write the list to disk anyway, you could
just use the sort program. If you're familiar with objects, AFAIK there's
a TSortedCollection which could also do the job.

There are some other issues with your program you should have a look at.
For example, it is a bit unclear to me what all the file operations in
the main program are supposed to do.

 - Sebastian

--
YOUR AD HERE!

Re:ALL recursive subdirectories


Quote
Keza wrote:

>          If MP3Search.Attr<>Directory Then

This seems dangerous. (xxx.Attr and Directory) = 0 is preferred.

Quote
>            Begin
>              MP3mem.Name:=Path+MP3Search.Name;
>              MP3mem.Size:=MP3Search.Size;

maybe this one helps:
http://bsn.ch/tp-links
page "FAQ" look for "Recursion example, program Suche".

I must admit that this program is not very clever, especially with
sorting. I should have built an array of records for sorting. And
the array puts some limitation on the count of files.
Today I would use a TSortedCollection instead.
:-)
--
Franz Glaser, Glasau 3, A-4191 Vorderweissenbach Austria +43-7219-7035-0
Muehlviertler Elektronik Glaser.  Industrial control and instrumentation
http://members.eunet.at/meg-glaser/           mailto:meg-gla...@eunet.at
http://www.geocities.com/~franzglaser/ http://members.xoom.com/f_glaser/

Re:ALL recursive subdirectories


Quote
> This seems dangerous. (xxx.Attr and Directory) = 0 is preferred.

Thanks for your help I don't see why it is dangerous but I changed it any
way below is what I have at the moment.
The file operations in the main program are for writing the lists to a data
file (I only copied the relevant code over so you may have missed a bit of
it). I have been reading an article on C++ and it talks about making memory
when it is needed and deleting it when it is not, so instead of having a
huge array for sorting a few numbers and wasting memory or worse having more
numbers then memory is not an issue. Is there something similar and EASY for
Pascal. Otherwise I will have to try and sort it from the datafile,
shouldn't be too hard?

Procedure ListAll(Root : String);
Var MP3Search,DIRSearch : SearchRec;
    Dir : DirStr;
    Name : NameStr;
    Ext : ExtStr;
    Stack : Word;
Begin
     If SPtr<Stack Then Stack:=SPtr;
     Root:=FExpand(Root);
     FSplit(Root,Dir,Name,Ext);
     If First Then
       Begin
         Stack:=SPtr;
         FindFirst(Root,Anyfile,MP3Search);
         While DosError=0 Do
           Begin
             If (MP3Search.Attr and Directory)=0 Then
               Begin
                 MP3mem.Name:=Dir+MP3Search.Name;
                 MP3mem.Size:=MP3Search.Size;
                 Write(MP3File,MP3Mem);
               End;
             FindNext(MP3Search);
           End;
         First:=False;
       End;
     FindFirst(Root,Anyfile,DIRSearch);
     While DosError=0 Do
       Begin
         If ((DIRSearch.Attr and Directory)=Directory) and
(DIRSearch.Name<>'.') and (DIRSearch.Name<>'..') Then
           Begin
             FindFirst(Dir+DIRSearch.Name+'\*.*',Anyfile,MP3Search);
             While DosError=0 Do
               Begin
                 If (MP3Search.Attr and Directory)=0 Then
                   Begin
                     MP3mem.Name:=Dir+DIRSearch.Name+'\'+MP3Search.Name;
                     MP3mem.Size:=MP3Search.Size;
                     Write(MP3File,MP3Mem);
                   End;
                 FindNext(MP3Search);
               End;
             ListAll(Dir+DIRSearch.Name+'\*.*');
           End;
         FindNext(DIRSearch);
       End;
End;

{This bit starts the procedure}
     Assign(MP3File,MP3FileLoc);
     Rewrite(MP3File);
     First:=True;
     ListAll(InDir+'\*.*');

Re:ALL recursive subdirectories


Quote
Keza <mcdon...@flatrate.net.au> wrote:
> making memory when it is needed and deleting it when it is not <snip>...
> Is there something similar and EASY for Pascal.

Learn how to use the heap. Look up new() and dispose() for the actual memory
allocation, and study linked lists and related structures. It's not really
all that hard.

--
______________________________________________________________________
     The Scarlet Manuka,      |        Nitpickers' Party motto:
  Pratchett Quoter At Large,  |  "He who guards his lips guards his
 First Prophet of Bonni, is:  |  soul, but he who speaks rashly will
   sa...@maths.uwa.edu.au     |    come to ruin." -- Proverbs 13:3
______________________________|_______________________________________

Re:ALL recursive subdirectories


Quote
Keza wrote:

> The file operations in the main program are for writing the lists to a data
> file (I only copied the relevant code over so you may have missed a bit of
> it).
> I have been reading an article on C++ and it talks about making memory
> when it is needed and deleting it when it is not, so instead of having a
> huge array for sorting a few numbers and wasting memory or worse having more
> numbers then memory is not an issue. Is there something similar and EASY for
> Pascal. Otherwise I will have to try and sort it from the datafile,
> shouldn't be too hard?

This is a matter of the heap. "Turbo Pascal Memory considerations"
in page "FAQ" of the http://bsn.ch/tp-links
will explain it.

But, why not use the TSortedCollection of the OBJECTS.PAS? It has
the heap management built in.

:-)
--
Franz Glaser, Glasau 3, A-4191 Vorderweissenbach Austria +43-7219-7035-0
Muehlviertler Elektronik Glaser.  Industrial control and instrumentation
http://members.eunet.at/meg-glaser/           mailto:meg-gla...@eunet.at
http://www.geocities.com/~franzglaser/ http://members.xoom.com/f_glaser/

Re:ALL recursive subdirectories


It was fairly easy to sort the datafile I had amde without an array but it
is much slower I have around 780 files that it lists and sorts and it takes
about 40 seconds to order them by size (this would be because it is on disk
not in memory) any ideas on how to make it faster (besides buying a faster
hard drive he he he).

program  file_sorter;
uses Crt,Dos;
Type MP3Info = Record
                 Name : String;
                 Size : LongInt;
               End;
Var MP3File,SLMP3File : File Of MP3Info;
    MP3Mem,SLMP3Mem : MP3Info;
    Total,Number,I,J : Integer;
    Size : LongInt;
    Finish,First,Found : Boolean;
    temp: integer;

Procedure ListAll(Root : String);
Var MP3Search,DIRSearch : SearchRec;
    Dir : DirStr;
    Name : NameStr;
    Ext : ExtStr;
    Stack : Word;
Begin
     If SPtr<Stack Then Stack:=SPtr;
     Root:=FExpand(Root);
     FSplit(Root,Dir,Name,Ext);
     If First Then
       Begin
         Stack:=SPtr;
         FindFirst(Root,Anyfile,MP3Search);
         While DosError=0 Do
           Begin
             If (MP3Search.Attr and Directory)=0 Then
               Begin
                 MP3mem.Name:=Dir+MP3Search.Name;
                 MP3mem.Size:=MP3Search.Size;
                 Write(MP3File,MP3Mem);
               End;
             FindNext(MP3Search);
           End;
         First:=False;
       End;
     FindFirst(Root,Anyfile,DIRSearch);
     While DosError=0 Do
       Begin
         If ((DIRSearch.Attr and Directory)=Directory) and
(DIRSearch.Name<>'.') and (DIRSearch.Name<>'..') Then
           Begin
             FindFirst(Dir+DIRSearch.Name+'\*.*',Anyfile,MP3Search);
             While DosError=0 Do
               Begin
                 If (MP3Search.Attr and Directory)=0 Then
                   Begin
                     MP3mem.Name:=Dir+DIRSearch.Name+'\'+MP3Search.Name;
                     MP3mem.Size:=MP3Search.Size;
                     Write(MP3File,MP3Mem);
                   End;
                 FindNext(MP3Search);
               End;
             ListAll(Dir+DIRSearch.Name+'\*.*');
           End;
         FindNext(DIRSearch);
       End;
End;

begin
     clrscr;
     First:=True;
     Assign(MP3File,'MP3z.Dat');
     Rewrite(MP3File);
     Listall('C:\KEIRAN\MP3z\*.*');
     For I:=0 to Filesize(MP3File)-2 do
       begin
         for J:=I+1 to Filesize(MP3File)-1 do
           begin
             Seek(MP3File,I);
             Read(MP3File,MP3Mem);
             Seek(MP3File,J);
             Read(MP3File,SLMP3Mem);
             if MP3Mem.Size<SLMP3Mem.Size Then
               begin
                 Seek(MP3File,I);
                 Write(MP3File,SLMP3Mem);
                 Seek(MP3File,J);
                 Write(MP3File,MP3Mem);
               end;
             end;
           end;
           for I:=0 to Filesize(MP3File)-1 do
             Begin
               Seek(MP3File,I);
               Read(MP3File,MP3Mem);
               writeln(MP3Mem.Name,' ',MP3Mem.Size);
             End;
     Close(MP3File);
     Erase(MP3File);
          readln;
end.

Re:ALL recursive subdirectories


In article <388515af@commerce>,
  "Keza" <mcdon...@flatrate.net.au> wrote:

Quote
> It was fairly easy to sort the datafile I had amde without an array
> but it is much slower I have around 780 files that it lists and sorts
> and it takes about 40 seconds to order them by size (this would be
> because it is on disk not in memory) any ideas on how to make it
> faster (besides buying a faster hard drive he he he).

You've given the solution yourself:

"this would be because it is on disk not in memory"

And to add insult to injury, you're using Bubble sort...

Sort in memory, either by building a list (look on Deja for the method
to do so), or by building an array of pointers to data on the heap and
sorting the pointers. I think I posted something (again look on Deja) to
do so a heapsort - in one of my programs I have to sort a file four
times, with two keys for each sort. The file is about the size of yours.
On a 350Mhz PII, it is sorted and reformatted when I release the Enter
key.

Robert
--
Robert AH Prins
prin...@willis.com

Sent via Deja.com http://www.deja.com/
Before you buy.

Re:ALL recursive subdirectories


In article <863ucd$ni...@nnrp1.deja.com>,
Robert AH Prins  <prin...@williscorroon.com> wrote:

Quote
>In article <388515af@commerce>,
>  "Keza" <mcdon...@flatrate.net.au> wrote:

>And to add insult to injury, you're using Bubble sort...

Yes, if there ever was a case where one should burn books one should
burn books that teach that POS algorithm. It gives people the idea that
sorting is somehow hard thing to do. On 40 seconds a good sort would
sort millions of elements in modern computers.

The fastest general sorting method I know (especially on TP/BP
environment with limited segment sizes) is recursive mergesort on
linked lists. I wrote a soft filter that can sort a file of 24700 lines
(almost a megabyte) in 6.5 seconds (The actual sorting time is about
2.1 seconds, rest is IO) and that is on a 486. Sorting is actually a
very light task provided one uses proper algorithms.

A goof starting for for fast sorting methods is shellsort:

Type CompareFunc=Function(i,j:integer):Boolean;
     SwapProc=Procedure(i,j:integer);

Procedure ShellSort(first,n:integer;compare:CompareFunc; Swap:SwapProc);

var i,j,incr,last:integer;
Begin
  incr:=longint(n)*10 div 17;
  last:=n-1+first;

  while incr>0 do begin
    for i:=first to last-incr do begin
      j:=i;
      while (j>=first) and Not compare(j,j+incr) do begin   { Short circuit! }
          Swap(j,j+Incr);
          dec(j,incr);
      End
    End;
    incr:=longint(incr)*10 div 17;
  End;
End;

Osmo

Other Threads