Announcement

Collapse
No announcement yet.

Verify a file's existence?

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Verify a file's existence?

    Does anyone have a suggestion for verifying a file's existence?
    When I try via DIR$, and check to see if the file
    "C:\ABC\Specific.dat" exists, it doesn't ast like it wants to
    work in the directory again if it doesn't find it. I am looking
    for a way to repeatedly check for the same file in the same
    directory until it is found, or timed out.

    Ideally (for me anyway), it would be nice be able to do something
    like:
    FileExistQ=0
    While FileExistQ=0
    FileExistQ=ChekFile "C:\ABC\Specific.dat"
    wend

    Yes, it will repeat. But hopefully not for long, a previous
    routine is creating Specific.dat. I just need to know when
    it is done so I can open it. It often tries to open it in the
    middle of its creation, it seems.

    Any suggestions?

    Thank you.

    Robert

    ------------------

  • #2
    Robert,
    the following "exist" function is included in DOSUNIT.BAS.

    Code:
    '============================================================================
    ' Exist - Return true (-1) if a given filespec exists.  Preserves the DTA.
    '         Calling any of the DTA routines after Exist will return invalid
    '         results because of the DTA preservation.
    '
    ' Filename = name of file or directory to test for the existence of
    '
    FUNCTION Exist(BYVAL Filename AS STRING) PUBLIC AS INTEGER
    
      DIM DtaSeg       AS INTEGER
      DIM DtaOFs       AS INTEGER
      DIM OldDtaBuffer AS STRING
    
      GetDTA DtaSeg, DtaOfs
    
      DEF SEG = DtaSeg
        OldDtaBuffer = PEEK$(DtaOfs, 44)     'save current DTA information
      DEF SEG
    
      FUNCTION = LEN( DIR$(Filename, 17) ) > 0
    
      DEF SEG = DtaSeg
        POKE$ DtaOfs, OldDtaBuffer           'restore saved DTA information
      DEF SEG
    
    END FUNCTION
    Paul.

    ------------------


    [This message has been edited by Paul Dixon (edited February 05, 2005).]

    Comment


    • #3
      It often tries to open it in the middle of its creation, it seems.

      Well, it will..

      What you "could" do is this:
      Code:
      WHILE s = ""
        S = DIR$(myfilename$)
      WEND
      .. but that runs the risk of trying to use the file "in the middle of its creation" as you have observed.

      What would probably be superior here is to try to open the file for exclusive use, retrying if you can't get it.

      Code:
      FUNCTION WaitForFileToBeAvailable (S AS STRING) AS LONG
      
       LOCAL hFILE AS LONG, E AS LONG
      
       hFile  = FREEFILE
       E      = 1 
       DO WHILE E
          IF DIR$(S) THEN
             OPEN S FOR RANDOM ACCESS READ WRITE LOCK READ WRITE AS hFile
             E = ERR
          END IF
          '  I might put in a DELAY here
       LOOP
       CLOSE hFile
      END FUNCTION
      This will loop until you obtain the file for exclusive use, then CLOSE the file

      (I check the DIR$ each time thru loop because I'm not sure at what point DIR$ will return something, i.e., DIR$ might not show the file as in existence yet, and OPENing for RANDOM will create it.. which you do not want to happen).

      I haven't tested this, but it should work.

      MCM

      Michael Mattias
      Tal Systems Inc. (retired)
      Racine WI USA
      [email protected]
      http://www.talsystems.com

      Comment


      • #4
        Michael-

        Errors on my end:
        LOCAL hFILE AS LONG, E AS LONG End of statment expected
        IF DIR$(S) THEN Relational operator missing

        The first one I don't know how to correct since I have not
        worked with LOCAL before. Does the second one need an "ISTRUE"?

        Thanks.

        Robert

        ------------------

        Comment


        • #5
          DOS or windows doesn't actually write the file size until the
          buffer(s) are flushed and the file is closed. As such, you
          need to see if the file size > 0.

          There is a way of determining the size of a file without
          opening it. I wrote the below code back on the days of PB/DOS
          2.1f so you may want to cut me some slack here. There's a bit
          more than you may want or need but.....
          Code:
          	$lib all off
                  $stack &h1024
                  color 14,1
                  cls
          
          	path$ = "c:\dos\"
          
          	mm$ = dir$(path$ + "*.*")
          
          	do until mm$ = ""
          	if inkey$ = chr$(27) then exit loop
                  dummy = file.data(mm$)
                  fd$ = file.date$
                  ft$ = file.time$
                  fa$ = file.attr$
                  fs$ = file.size$
                  print;mm$;tab(14);fd$;_
                            tab(25);ft$;_
                            tab(34);fa$;_
                            tab(43);fs$
          '
          	mm$ = dir$
          	loop
          '
          	end
          
          REM **************************************************
          REM *                                                *
          REM * This is the "do-it-all" function. It collects  *
          REM * all four pieces of data for the specified file *
          REM *                                                *
          REM **************************************************
          REM *                                                *
          REM * Although listed, the file name is not returned *
          REM * by this function since you presumibly already  *
          REM * have it.                                       *
          REM *                                                *
          REM **************************************************
          
          function file.data(d$)
                  shared file.date$, file.time$, file.attr$, file.size$
          
          REM *******************
          REM *                 *
          REM * get DTA address *
          REM *                 *
          REM *******************
          
          	reg 1,&h2f00
                  call interrupt &h21
          
                  segment = reg(9)		'DTA segment
                  offset  = reg(2)		'DTA offset
          
                  def seg = segment
                  y$ = peek$(offset,43)
                  def seg
          
                  file.attr$ = f.attr$(y$)
                  file.date$ = f.date$(y$)
                  file.time$ = f.time$(y$)
                  file.size$ = f.size$(y$)
                  file.flag$ = f.flag$
          
          	end function
          
          REM *********************************************
          REM *                                           *
          REM * Returns a BINARY string. Makes processing *
          REM * easier (in my opinion)                    *
          REM *                                           *
          REM *********************************************
          
          function f.attr$(y$)
          	te$ = bin$(asc(mid$(y$,22,1)))
                  do until len(te$) = 8
                  te$ = "0" + te$
                  loop
                  f.attr$ = te$
                  end function
          
          REM ********************************************
          REM *                                          *
          REM * Returns MM-DD-YYYY but you may change it *
          REM * as you see fit.                          *
          REM *                                          *
          REM ********************************************
          
          function f.date$(y$)
          
          	t1 = asc(mid$(y$,25,1))
                  t2 = asc(mid$(y$,26,1))
          
                  t1$ = bin$(t1)
                  do until len(t1$) = 8
                  t1$ = "0" + t1$
                  loop
          
                  t2$ = bin$(t2)
                  do until len(t2$) = 8
                  t2$ = "0" + t2$
                  loop
          
                  te$ = t2$ + t1$
          
          	year$  = "&b" + mid$(te$, 1,7)
                  month$ = "&b" + mid$(te$, 8,4)
                  day$   = "&b" + mid$(te$,12,5)
          
          	year  = val(year$) + 1980
                  month = val(month$)
                  day   = val(day$)
          
          	te$ = using$("##",month) + "-" + _
                        using$("##",day)   + "-" + _
                        using$("####",year)
          	replace " " with "0" in te$
                  f.date$ = te$
          	end function
          
          REM *********************************************
          REM *                                           *
          REM * Returns HH:MM:SS in 24-hour format but    *
          REM * you may change it as you see fit.         *
          REM *                                           *
          REM *********************************************
          
          function f.time$(y$)
          
          	t1 = asc(mid$(y$,23,1))
                  t2 = asc(mid$(y$,24,1))
          
                  t1$ = bin$(t1)
                  do until len(t1$) = 8
                  t1$ = "0" + t1$
                  loop
          
                  t2$ = bin$(t2)
                  do until len(t2$) = 8
                  t2$ = "0" + t2$
                  loop
          
                  te$ = t2$ + t1$
          
          	hour$  = "&b" + mid$(te$, 1,5)
                  minu$  = "&b" + mid$(te$, 6,6)
                  seco$  = "&b" + mid$(te$,12,5)
          
                  hour  = val(hour$)
                  minu  = val(minu$)
                  seco  = val(seco$)
          
          	te$ = using$("##",hour) + ":" + _
                        using$("##",minu) + ":" + _
                        using$("##",seco)
          	replace " " with "0" in te$
                  f.time$ = te$
          	end function
          
          REM ****************************
          REM *                          *
          REM * Returned in STRING form. *
          REM *                          *
          REM ****************************
          
          function f.size$(y$)
          	t1 = asc(mid$(y$,27,1))
          	t2 = asc(mid$(y$,28,1))
          	t3 = asc(mid$(y$,29,1))
          	t4 = asc(mid$(y$,30,1))
          
          	t1&& =  t1 + (t2 * 256)
                  t2&& = (t3 + (t4 * 256)) * 65536
                  te$ = str$(t1&& + t2&&)
                  f.size$ = remove$(te$," ")
          	end function
          
          function bin.2.asc(tt$)
                  mm$ = ""
          
                  for x = len(tt$) to 1 step -1
                   mm$ = mm$ + mid$(tt$,x,1)
                    next x
          
                  for x = 1 to len(mm$)
                   z$ = mid$(mm$,x,1)
                    if z$ = "1" then
                     t = t + (2 ^ (x-1))
                      end if
                       next x
          
                  Bin.2.ASC = t
          	end function
          
          $if 0
          	decoding the flag register (reg 0)
                  Protected mode flag register structure
          
                  1  1  1  1  1  1
                  5  4  3  2  1  0  9  8  7  6  5  4  3  2  1  0
                  ----------------------------------------------
                  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
                 -----------------------------------------------
                  x  ^  ^  ^  ^  ^  ^  ^  ^  ^  x  ^  x  ^  x  ^
                     ³  ³  ³  ³  ³  ³  ³  ³  ³     ³     ³     À> Carry flag
                     ³  ³  ³  ³  ³  ³  ³  ³  ³     ³     ÀÄÄÄÄÄÄ> Parity flag
                     ³  ³  ³  ³  ³  ³  ³  ³  ³     ÀÄÄÄÄÄÄÄÄÄÄÄÄ> Auxillary flag
                     ³  ³  ³  ³  ³  ³  ³  ³  ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ> Zero flag
                     ³  ³  ³  ³  ³  ³  ³  ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ> Sign flag
                     ³  ³  ³  ³  ³  ³  ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ> Trap flag
                     ³  ³  ³  ³  ³  ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ> Interrupt flag
                     ³  ³  ³  ³  ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ> Direction flag
                     ³  ³  ³  ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ> Overflow flag
                     ³  ÀÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ> IOPL
                     ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ> Nested flags
          
          	If the file attribute bit data are set to "1" then
          
                  0  0  0  0  0  0  0  0
                  ^  ^  ^  ^  ^  ^  ^  ^
                  ³  ³  ³  ³  ³  ³  ³  ÀÄ> File is write protected
                  ³  ³  ³  ³  ³  ³  ÀÄÄÄÄ> File is hidden
                  ³  ³  ³  ³  ³  ÀÄÄÄÄÄÄÄ> System file
                  ³  ³  ³  ³  ÀÄÄÄÄÄÄÄÄÄÄ> Volume name
                  ³  ³  ³  ÀÄÄÄÄÄÄÄÄÄÄÄÄÄ> Sub-directory
                  ³  ³  ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ> Archive (Not sure which is which)
                  ÀÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ> Not used as of yet
          $endif

          ------------------
          There are no atheists in a fox hole or the morning of a math test.
          If my flag offends you, I'll help you pack.

          Comment


          • #6
            >LOCAL hFILE AS LONG, E AS LONG End of statment expected

            Forgot PB/DOS does not do LOCAL that way.

            >IF DIR$(S) THEN Relational operator missing
            IF DIR$(s) > "" THEN << correct

            >DOS or windows doesn't actually write the file size until the
            >buffer(s) are flushed and the file is closed

            When does it "exist" to the DIR$ function? As soon as it's opened? Not till it's closed?

            As far as checking for (exists) AND (filesize >0), that makes sense as long as it's not possible to have a size zero file be 'real' . ( I got burned by that once).

            Michael Mattias
            Tal Systems Inc. (retired)
            Racine WI USA
            [email protected]
            http://www.talsystems.com

            Comment


            • #7
              When does it "exist" to the DIR$ function? As soon as it's opened? Not till it's closed?
              The O/S writes the file name when it's opened. It's then visible
              to DIR$.

              This can be checked when doing a backup (assuming you can get
              there in time).

              During the backup, drop to the DOS prompt, switch to the directory
              you are doing the backup in and do a DIR. You will see the file name
              with a file length of zero. This is if you replace and not append
              the backup file.

              It's only after the file has been fully written, the buffers flushed
              and the file is closed that the O/S will write the file size.


              ------------------


              [This message has been edited by Mel Bishop (edited February 05, 2005).]
              There are no atheists in a fox hole or the morning of a math test.
              If my flag offends you, I'll help you pack.

              Comment


              • #8
                Michael & Mel-

                Thank you both. Its too lengthy to go into why I am wanting to
                do this, so let me write it off to this: A client who wants
                things to work on her DOS 6.0 machine *at least* as well as
                those nifty computers on Enterprise.

                Thanks again.

                Robert

                ------------------

                Comment


                • #9
                  For Mel Bishop, please

                  Mel-

                  I have been trying to find where in your program that would
                  cause a data file to empty out, i.e., delete the contents?

                  When I run the routine on the file I am looking for, the file's
                  contents becomes empty.

                  Example:
                  Filename: DrvDataZ.dat
                  Contains one line:
                  Z:\Gendata\Data\Demo\Sample of the Washingtons.abc

                  It reads it to get a file size, but then everything disappears.
                  Can I prevent this? I need to preserve the contents since I
                  will read them again elsewhere in the program.

                  Thank you.

                  Robert



                  ------------------

                  Comment


                  • #10
                    >It reads it to get a file size, but then everything disappears.

                    Show code you use to get file size and to read the lines of data.

                    Michael Mattias
                    Tal Systems Inc. (retired)
                    Racine WI USA
                    [email protected]
                    http://www.talsystems.com

                    Comment


                    • #11
                      Checking the length of a file just requres using LOF(#filennum)
                      function. Reading the contents of a file does not "delete" the
                      contents, but if you do not reposition to the start of the file
                      (by either closing, then reopening the file, or by using SEEK),
                      then you will be attempting to read what's in the file AFTER the
                      line you last read. In your case, nothing follows.

                      ------------------
                      Old Navy Chief, Systems Engineer, Systems Analyst, now semi-retired

                      Comment


                      • #12
                        I'm not sure what you mean by "empty out, i.e., delete the
                        contents". If you mean delete the file, it shouldn't. It should
                        run as advertised. However, the following is a stripped down
                        version returning only the file size. It was edited "on the fly"
                        and hasn't been tested.
                        Code:
                            $lib ALL OFF
                            COLOR 14,1
                            CLS
                        '
                            d$ = "c:\autoexec.bat"
                            d$ = DIR$(d$)
                        '
                            PRINT;file.size$(d$)
                            END
                        '
                        FUNCTION file.size$(d$)
                        '
                        REM *******************
                        REM *                 *
                        REM * get DTA address *
                        REM *                 *
                        REM *******************
                        '
                            reg 1,&h2f00
                            CALL interrupt &h21
                        '
                            segment = reg(9)        'DTA segment
                            offset  = reg(2)        'DTA offset
                        '
                            def seg = segment
                             y$ = PEEK$(offset,43)
                              def seg
                        '
                            t1 = ASC(MID$(y$,27,1))
                             t2 = ASC(MID$(y$,28,1))
                              t3 = ASC(MID$(y$,29,1))
                               t4 = ASC(MID$(y$,30,1))
                        ' 
                            t1&& =  t1 + (t2 * 256)
                            t2&& = (t3 + (t4 * 256)) * 65536
                            te$ = STR$(t1&& + t2&&)
                            FUNCTION = REMOVE$(te$," ")
                            END FUNCTION



                        [This message has been edited by Mel Bishop (edited February 06, 2005).]
                        There are no atheists in a fox hole or the morning of a math test.
                        If my flag offends you, I'll help you pack.

                        Comment


                        • #13
                          Code:
                          'Code using PBCC or PBWIN  Not sure if DOS has this
                          ' Exist() function using GETATTR
                          FUNCTION Exist(File$) AS LONG
                            LOCAL Dummy&
                            Dummy& = GETATTR(File$)
                            FUNCTION = (ERRCLEAR = 0)
                          END FUNCTION
                          [This message has been edited by Mike Doty (edited February 06, 2005).]
                          How long is an idea? Write it down.

                          Comment


                          • #14
                            PB/DOS has FILEATTR, but that requires an open handle.

                            Also: GETATTR fails in your example if File$ specifies a root directory (e.g., File$= "P:\").
                            Michael Mattias
                            Tal Systems Inc. (retired)
                            Racine WI USA
                            [email protected]
                            http://www.talsystems.com

                            Comment

                            Working...
                            X