File Management

File Management Function

DeleteFile Deletes an error-tolerant file
ExeName Full File Name of Executable ( Application )
File Tests for the existence of file(s)
FileMove Moves file(s) to another directory
FileDelete Deletes file(s) by name and attribute
FileSeek Searches for files by name and attribute
HB_FNameExists Detect File / Folder existence
HB_ProgName Returns name and directory of the current Harbour program
HB_FileExists Tests for the existence of a file
HB_FileMatch Makes a file comparison with mask
HB_FTempCreate Creates and opens a temporary file
HB_FTempCreateEx Creates and opens a temporary file with extension
RenameFile Fault tolerant renaming of a file
TempFile Creates a file for temporary use

HB_DirScan

HB_DirScan

Scan a directory tree and build a files and folders list

Syntax

      hb_DirScan(<cPath>, [<cFileMask>], [<cAttr>]) --> <aFiles>

Arguments

<cPath> : A character string holding the drive, directory and/or file specification to retrieve information for. Default is current directory.

<cFileMask> : For filter files to add to the list, (can include wild card characters). Default is ‘*.*’.

<cAttr> : A character string holding file attributes can be specified. Information about files carrying these attributes is retrieved. One or more characters of the table below can be included in . For add directories to the list add ‘D’ to .

Attributes for HB_DirScan() :

         Attribute Meaning
         --------- -------------------------
             A     Archive
             D     Directories
             H     Hidden files
             R     Read-only
             S     System files

Returns

<aFiles> : A two-dimensional array of five columns; holding information about files in the and the that match . An empty array, if no matched file found or an error occured.

Description

The HB_DirScan() function is similair to the Directory(). The first difference is that HB_DirScan() scans recursively all sub- directories in the directory specified with. And second difference is Directory() don’t requires parameter, instead this info included in the .

The result is a two dimensional array . Columns can be accessed using #define constants from the DIRECTRY.CH file.

Constants for the HB_DirScan() array :

         Symbolic Numeric
         Constant Value  Meaning             Data Type
         -------- -----  ------------------- --------------
         F_NAME     1    File name           Character
         F_SIZE     2    File size in bytes  Numeric
         F_DATE     3    File date           Date
         F_TIME     4    File time           Character
         F_ATTR     5    File attributes     Character

Files

Header: Directry.ch

Example

      Assuming this directory tree and files exist :

      C:\
         | temp                     D
         + ---- + Dir1              D
                |      doc1.docx    F
                |      test1.bat    F
                |      test1.txt    F
                + Dir2              D
                |      doc2.docx    F
                |      test2.bat    F
                |      test2.txt    F
                + run.bat           F
                  test.bat          F
                  test.exe          F

      PROC TestDScan()

         LOCAL aFFList := HB_DirScan( "C:\TEMP" )

         LOCAL x1Row

         FOR EACH x1Row IN aFFList
            ? PAD( x1Row[ 1 ], 23 ),;                     // Name
              TRAN( x1Row[ 2 ], '999,999,999,999' ),;     // Size
              x1Row[ 3 ],;                                // Date
              x1Row[ 4 ],;                                // Time
              x1Row[ 5 ]                                  // Attributes
         NEXT x1Row

      RETU // TestDScan()

      Result :

         Dir1\doc1.docx       14,757 26.02.2014 00:04:27 A
         Dir1\test1.bat           54 24.02.2014 00:54:01 A
         Dir1\test1.txt           54 24.02.2014 00:54:01 A
         Dir2\doc2.docx       14,757 26.02.2014 00:04:27 A
         Dir2\test2.bat           54 24.02.2014 00:54:01 A
         Dir2\test2.txt           54 24.02.2014 00:54:01 A
         run.bat               24 27.02.2014 01:12:28 A
         test.bat                 54 24.02.2014 00:54:01 A
         test.exe          1,413,285 27.02.2014 01:10:36 A

      ˜˜˜˜˜˜˜

      HB_DirScan( "C:\TEMP\*.txt" ) <- Incorrect call !

      ˜˜˜˜˜˜˜

      HB_DirScan( "C:\TEMP\", "*.txt" )

      Result :

         Dir1\test1.txt           54 24.02.2014 00:54:01 A
         Dir2\test2.txt           54 24.02.2014 00:54:01 A

Seealso

Directory(), File(), FileSeek(), HB_FileMatch()HB_FileExists(), HB_FNameExists(), HB_DirExists()FileFindXxxx

FileFindXxxx

FileFindXxxx

Searches for files by name and attribute and get file properties

Syntax :

      FileFindFirst( <cFileNameMask>, @<pFFindInfo>[, <nAttr> ] ) -> <lFound>
      FileFindNext(  <pFFindInfo> ) -> <lFound>
      FileFindName(  <pFFindInfo> ) -> <cFileName>
      FileFindAttr(  <pFFindInfo> ) -> <nAttr>
      FileFindSize(  <pFFindInfo> ) -> <nSize>
      FileFindDate(  <pFFindInfo> ) -> <dDate>
      FileFindTime(  <pFFindInfo> ) -> <cTime>

Arguments

<cFileNameMask> : A file name including its path and drive designation. It may contain wildcards.

<pFFindInfo> : A pointer for an internal data structure to hold file(s) info

<nAttr> : The file attribute that corresponds to the ones described in the table on the next page. The default value is 0.

         Coding the File Attribute
         ----------------------------------------------------------------
         Value Symb. constants        Assigned attribute
         ----------- ---------------- -----------------------------------
             0       FA_NORMAL
             1       FA_READONLY      READ ONLY (Read-only)
             2       FA_HIDDEN        HIDDEN (Hidden files)
             4       FA_SYSTEM        SYSTEM (System files)
             8       FA_VOLUME        VOLUME (Name of a floppy/hard disk)
            16       FA_DIRECTORY     DIR (Directory)
            32       FA_ARCHIVE       ARCHIVE (Changes since last backup)
         ----------------------------------------------------------------

Returns

<lFound> : A logical value indicate file existence

<cFileName> : Name of file found by FileFindFirst() or FileFindNext() (without drive/dir)

<nAttr> : A numeric value indicate attribute info of file

<nSize> : A numeric value indicate size of file

<dDate> : A date value indicate date of file

<cTime> : A character value indicate time of file (as “HH:MM:SS”)

Description

FileFindXxxx functions provides a set of info on a set of file.

Calling first FileFindFirst() build an internal data structure ( probably an array like returned by Directory() ). And then calling other FileFindXxxx functions returns individual file info for last file found.

This function set look like FileSeek() function. For more info look at it.

Note

Internal Data Buffer : Every FileFindXxxx() function uses internal data structure <pFFindInfo>. For further using this variable should be passed by reference in FileFindFirst(). May be useful release this buffer by go out of scope or be explicitly release by freeing <pFFindInfo> variable a way like this:

<pFFindInfo> := NIL

Example

      PROC TestFFs()
         LOCAL pFFInfo
         LOCAL nFileNo := 0
         LOCAL lContinue := FileFindFirst( '*.*', @pFFInfo )

         WHIL lContinue
            ? PAD( ++nFileNo, 3),;
              PAD( FileFindName( pFFInfo ), 23 ),;
                   FileFindAttr( pFFInfo ),;
                   FileFindSize( pFFInfo ),;
                   FileFindDate( pFFInfo ),;
                   FileFindTime( pFFInfo )
            lContinue := FileFindNext( pFFInfo )
         END

         RETU // TestFFs()

Seealso

Directory(), FileSeek(), FileAttr(), FileDate(), FileSize(), FileTime(), HB_FileMatch()

Directory and long path names

Hi,

> directory() and related function

DIRECTORY() in Harbour makes the same job as in Clipper. The only differences are platform dependent. Harbour supports wider set of attributes.

Wildcards are also platform dependent. In *nixes fnmatch() function is used internally with the following extensions: * – any number of characters

? – exactly one character. In DOS/OS2/WIN it accepts also “no character” is it’s at the end of filename part. [] – enclose group of characters, i.e. [abc] – characters “a”, “b” and “c” [a-z] – range of characters from “a” to “z” [-A-F0-9.] – characters: – A B C D E F 0 1 2 3 4 5 6 7 8 9 . please also remember that in *nixes file systems uses case sensitive names.

Mask which covers all files is “*”, function hb_osFileMask() returns mask for all files on given platform.

In DOS, OS2 and MS-Windows Mask which covers all files is “*.*” “*” is only for files without extension. In *nixes “*.*” means files which have “.” in the name. In MS-Windows (and maybe also DOS and OS2 with LFN support) there are some tricks which tries to emulate DOS behavior with fixed 8.3 format. I do not know exact tricks they implemented.

Some simple mapping like support for all files with mask like ???????.??? can be easy detected but if you made some more advances masks, i.e. with more then one dot then the behavior is really funny.

Anyhow in functions like directory() in DOS, OS2 and MS-Win file mask is interpreted by system not Harbour so the differences to expected behavior should be reported to MS not us. In these systems only one Harbour function: hb_FileMatch() makes own file mask comparison. Anyhow the differences are can appear only due to missing DOS hacks. In *nixes hb_FileMatch() uses internally fnmatch() so here OS evaluates passed file masks. BTW hb_DirScan() uses internally hb_FileMatch().

best regards,
Przemek

FileSeek Function

FileSeek

Searches for files by name and attribute

Syntax :

      FileSeek([<cFileMap>, [<nFileAttr>], [<lExact>]])  --> cFileName

Arguments

<cFileMap> : Designates a file name including its path and drive designation. It may contain wildcards.

<nFileAttr> : Designates the file attribute that corresponds to the ones described in the table on the next page. The default value is 0.

<lExact> : If you designate .T. as the optional parameter, FileSeek() also checks for the exact agreement of the file attributes of the respective file with the value passed by <nFileAttr>.

If you call the function without parameters, it serves as a sequential call for a FileSeek() with file specifications, and returns sequential entries as long as these are found.

Returns

FileSeek() returns the name of the first or next entry (when called without parameter) located in the selected directory.

Description

FileSeek() provides the foundation for a variety of functions. As a group, they permit access to desired information about directory entries. Implement the FileSeek() function when you want information about a file group (wildcards). When you call it with the <cFileMap> parameter, it searches for the first entry in the designated directory. If you call it without parameters, it searches for the next matching entry in the directory. If no more entries are present, it returns a null string. An attribute mask can further define a file group that is being searched for. The desired file attributes are coded as follows:

        Table : Coding the File Attribute
        ------------------------------------------------------------------------
        Value Symb. constants        Assigned attribute
        ----------- ---------------- -------------------------------------------
            0       FA_NORMAL
            1       FA_READONLY      READ ONLY (Read-only)
            2       FA_HIDDEN        HIDDEN (Hidden files)
            4       FA_SYSTEM        SYSTEM (System files)
            8       FA_VOLUME        VOLUME (Name of a floppy/hard disk)
           16       FA_DIRECTORY     DIR (Directory)
           32       FA_ARCHIVE       ARCHIVE (Changes since last backup)
        ------------------------------------------------------------------------

If you implement multiple attributes simultaneously, the table values are added accordingly. Of course, not all combinations are useful.

Exact File Attributes :

DOS does not make an exact comparison with a designated attribute mask and attributes actually found in a file. Specify only the SYSTEM, HIDDEN, VOLUME, or DIR attributes for an entry to be found. Files with only one other attribute bit set are always returned, regardless of the value specified in the attribute mask. This way, a function call with a mask value of 16 returns not only sub-directories, but all files without a set attribute (e.g., all the ARCHIVE and R/O files).

To avoid this, you can designate .T. as the third parameter. The function itself also reviews the designated attribute mask with the actual file attributes, for an exact agreement. Then, the designation of a 16 mask and .T., only returns subdirectories.

Note

Internal Data Buffer :

Every time you use FileSeek() all the data for a directory entry is saved to an internal buffer. Individual information such as size, time, or date is easily accessible. To do this, the FILETIME(), FILEDATE(), etc., functions are called without parameters; otherwise, it requires another call to the disk, instead of taking the data from an internal buffer.

Examples :

      - Display the date and size of all files with the extension .TXT
        in a directory:

      cFile := FileSeek("C:\TEXT\*.TXT")

      DO WHILE .NOT. EMPTY(cFile)
         ? FileSize() // Size of file in buffer
         ? FileDdat() // Date of file in buffer
         cFile := FileSeek() // Search for next entry
      ENDDO

      - Display system files in the root directory. Attribute: READ
        ONLY, HIDDEN, SYSTEM, ARCHIVE --> 39, although 6(2 + 4) will
        suffice as an attribute:

      cFile := FileSeek("C:\*.*", 39)

      DO WHILE .NOT. EMPTY(cFile)
          ? cFile // File name
          cFile := FileSeek() // Look for next entry
      ENDDO

      - Only query the subdirectory:

        cSubDir := FileSeek("C:\*.*, 16, .T.)
        DO WHILE .NOT. EMPTY(cSubDir)
          ? cSubDir // Name of the directory
          cSubDir := FileSeek() // Search for next directory
        ENDDO
       *
       *
       -  Using FileSeek() as Directory() function

       PROC FLstFSeek() // File List by FileSeek()

         LOCAL cFileName,;
               nFileCount := 0,;
               nFAttr :=  1 +; // ReadOnly
                          2 +; // Hidden
                           4 +; // System
                         16    // Directory ( => 23 )

         SET DATE GERM
         SET CENT ON

          /* Display system files and directories in the root directory.
         Attribute: READONLY, HIDDEN, SYSTEM, DIRECTORY --> 23 */

         ? PAD( "File Name", 32 ), "Size Date Time Attribute"
         ? REPL( "-", 32 ), "--------------- ---------- -------- ---------"

         cFileName := FileSeek("C:\*.*", nFAttr)

         WHILE .NOT. EMPTY( cFileName )
             ++nFileCount
            ? PAD( cFileName, 32) ,; // File name
              TRAN( FILESIZE(), "999,999,999,999" ) ,;
              FILEDATE(),;
              FILETIME(),;
              TRAN( FILEATTR(), "99999,999" )

            cFileName := FileSeek() // Look for next entry
         ENDDO
         ?
         ? nFileCount, "Files and directories found."
         ?
         WAIT "End of FileSeek.prg"

      RETU // FLstFSeek()

Files

lib : hbct

Seealso

FileAttr(), FileDate(), FileSize(), FileTime(), HB_FileMatch(), Directory()