• Directory Listing

    From Robert Wolfe@1:116/18 to All on Thursday, November 27, 2014 06:13:02
    Hello everybody.

    I am trying to get a listing of files in the currently logged directory and output those to a text file. However, I cannot seem to figure out how to do this with the FindFirst() and FindNext() functions in FreePascal. The example I tried to base my own code on is as follows:

    Var
    Path : String;
    SR : TSearchRec;
    DirList : TStrings;
    begin
    if OpenPictureDialog1.Execute then
    begin
    Path:=ExtractFileDir(OpenPictureDialog1.FileName); //Get the path of the selected file
    DirList:=TStringList.Create;
    try
    if FindFirst('*.*', faArchive, SR) = 0 then
    begin
    repeat
    DirList.Add(SR.Name); //Fill the list
    until FindNext(SR) <> 0;
    FindClose(SR);
    end;

    //do your stuff

    finally
    DirList.Free;
    end;
    end;

    end;

    Unfortunately, I was not able to get my example (which follows) to work:

    Procedure GenDirFile ;
    Var SR: TSearchRec ;
    DirList: TStrings;
    Path: String;
    DirFile: Text;
    Begin ;
    Assign(DirFile, 'directory.lst') ;
    Rewrite(DirFile) ;
    DirList := TStringsList.Create;
    if FindFirst('*.zip', faArchive, SR) = 0 then
    begin
    repeat
    WriteLn(DirFile, SR.Name);
    until FindNext(SR) <> 0;
    FindClose(SR);
    end;
    Close(DirFile);
    End ;

    Is there something I am doing wrong here? Any help anyone can give would be greatly appreciated.

    Robert

    --- GoldED+/EMX 1.1.5-b20110223
    * Origin: Wolfe's OS/2 BBS * Memphis TN * os2.winserver.us (1:116/18)
  • From mark lewis@1:3634/12.71 to Robert Wolfe on Thursday, November 27, 2014 17:46:27

    On Thu, 27 Nov 2014, Robert Wolfe wrote to All:

    I am trying to get a listing of files in the currently logged
    directory and output those to a text file.

    ok, that's simple enough...

    However, I cannot seem to figure out how to do this with the
    FindFirst() and FindNext() functions in FreePascal. The example I
    tried to base my own code on is as follows:

    [chomp]

    Unfortunately, I was not able to get my example (which follows) to
    work:

    Procedure GenDirFile ;
    Var SR: TSearchRec ;
    DirList: TStrings;
    Path: String;
    DirFile: Text;
    Begin ;
    Assign(DirFile, 'directory.lst') ;
    Rewrite(DirFile) ;
    DirList := TStringsList.Create;
    if FindFirst('*.zip', faArchive, SR) = 0 then
    begin
    repeat
    WriteLn(DirFile, SR.Name);
    until FindNext(SR) <> 0;
    FindClose(SR);
    end;
    Close(DirFile);
    End ;

    Is there something I am doing wrong here?

    ok, there's several things going on here... i won't step through all of them but since you are attempting to use tstrings, let's go a little further and use
    a tstringlist instead... mainly because tstrings is designed to be inherited by
    other objects whch perform specialized tasks... tstringlist is one such object...

    the second thing is that you're not doing anything with the DirList that you've
    created... you are, however, attempting to write the filenames directly to your
    output file... that's ok but since we're using the tstringlist, all that stuff is done for you...

    there's a few other things but for now, let's look at this...

    1. create our tstringlist object
    2. fill our object with the files returned by findfirst/findnext
    3. when all files are found, write our stringlist to a file

    nice and easy... especially since the stringlist object already does a huge amount of heavy lifting for us ;)

    so here's the full code (!) of a working program... this was done on a vista machine using FPC's trunk code (FPC 2.7.1) from their repository... i also tested it on OS/2 eCS with FPC 2.6.4 and on a Linux with FPC 2.6.5 (the fixes branch of FPC 2.6)...

    ===== snip =====
    program DirectoryList;

    // we need the following unit libraries
    uses Sysutils, Classes;
    // Sysutils for findfirst and friends
    // Classes for TStringList and friends

    Procedure GenDirFile;
    Var SR: TSearchRec;
    DirList: TStringList;
    Begin;
    // create the class to hold the returned filenames
    DirList := TStringList.Create;
    // let's sort the list
    DirList.Sorted := True;
    if FindFirst('*.*', faArchive, SR) = 0 then
    begin
    repeat
    // add the returned filename to the list
    DirList.Add(SR.Name);
    until FindNext(SR) <> 0;
    // all done, close the find handle
    FindClose(SR);
    end;
    // now let's write our list of filenames to a text file.
    DirList.SaveToFile('directory.lst');
    End ;

    begin
    GenDirFile;
    end.
    ===== snip =====

    Any help anyone can give would be greatly appreciated.

    how's that? ;)


    (!) please try to reduce the problem to the minimal code needed for a working program that shows the failure or problem. partial code is ok in some cases but
    that'll come later ;)

    )\/(ark

    If you think it's expensive to hire a professional to do the job, wait until you hire an amateur.

    --- FMail/Win32 1.60
    * Origin: (1:3634/12.71)
  • From mark lewis@1:3634/12.71 to Robert Wolfe on Thursday, November 27, 2014 18:52:16

    Following up a post on Thu, 27 Nov 2014, from mark lewis to Robert Wolfe:

    a little further and use a tstringlist instead... mainly because
    tstrings is designed to be inherited by other objects whch perform specialized tasks... tstringlist is one such object...

    oh my... i can't believe i said that...

    to clarify... the program i returned to you uses classes... above i used the term "object" which is wrong in this case... i should have said "class"... objects are something else but they may operate in similar fashions...

    what's the difference between a class and an object? the main thing is that objects live on the stack whereas classes live in the heap... there's a whole lot more heap space than there is stack space... in a lot of today's world, classes are preferred over objects... likely because of this particular aspect...

    aside from that, one can think of classes and objects in the same way... both carry the code needed to access the data they contain...

    finally, close inspection of the documentation will show that the TStringList is derived from TStrings which is derived from TPersistent which is derived from TObject ;)

    PS: if you want the list of filenames sorted without case sensitivity, add

    DirList.CaseSensitive := False;

    after

    DirList.Sorted := True;

    ;)

    )\/(ark

    If you think it's expensive to hire a professional to do the job, wait until you hire an amateur.

    --- FMail/Win32 1.60
    * Origin: (1:3634/12.71)