Getting a filesize on read-only drives

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts
  • Chris Burgess
    Member
    • Apr 2008
    • 138

    Getting a filesize on read-only drives

    Hi,
    Can anyone tell us how to return the size of a single file?

    The below code works, but if the file is not present it creates a zero-length file with the name of the one we were checking for, so it presumably wouldn't work on a read-only network or an optical drive.

    Code:
    SUB TestSub() 
    
    Local Shellline As String
    LOCAL FileSize AS QUAD
    
    'in the final version, this value will be read from an INI file
    Shellline="q:\factory\metalwork\fanuc\OMD\transfer.exe"
    
    OPEN Shellline FOR BINARY AS #1
    FileSize = LOF(1)
    CLOSE #1
    
    'PrintQuad shows the returned value in a textbox
    PrintQuad FileSize
    Thanks in advance to anyone that can help.
  • Mel Bishop
    Member
    • May 1999
    • 3603

    #2


    Check "my" code near the bottom of the 1st page. The example returns the total size for all files matching specs but it should show you how to return for a single file.
    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

    • Gösta H. Lovgren-2
      Member
      • Sep 2002
      • 3238

      #3
      Originally posted by Chris Burgess View Post
      Hi,
      Can anyone tell us how to return the size of a single file?

      The below code works, but if the file is not present it creates a zero-length file with the name of the one we were checking for, so it presumably wouldn't work on a read-only network or an optical drive.
      ...
      In that case wouldn't the Sub return an ERROR code? (or at least the Open statement) Presumably you have an
      Code:
      If Err Then ...
      somewhere in the neighborhood.

      ===========================
      An investment in knowledge
      pays the best interest.
      Ben Franklin
      ===========================
      It's a pretty day. I hope you enjoy it.

      Gösta

      JWAM: (Quit Smoking): http://www.SwedesDock.com/smoking
      LDN - A Miracle Drug: http://www.SwedesDock.com/LDN/

      Comment

      • Dave Biggs
        Member
        • Feb 2001
        • 3808

        #4
        Try
        Code:
        OPEN Shellline FOR BINARY ACCESS READ AS #1
        Rgds, Dave

        Comment

        • Michael Mattias
          Member
          • Aug 1998
          • 43447

          #5
          CC5+, WIN 9+
          Code:
          LOCAL DD AS DIRDATA 
           S = DIR$ (filename) TO DD 
           File_Size =  DD.FilesizeLow  
           DIR$ CLOSE
          Michael Mattias
          Tal Systems (retired)
          Port Washington WI USA
          [email protected]
          http://www.talsystems.com

          Comment

          • Chris Burgess
            Member
            • Apr 2008
            • 138

            #6
            Gösta:
            Presumably you have an If Err Then somewhere in the neighborhood.
            Hi, thanks for your reply.
            I added Err to detect this condition, but have since found another issue with it. On a read-only drive, it returns an error 52 (bad file name or number), which can be used to detect this OK.

            The issue now is that the code can't differentiate between a valid zero-length file or the new file it creates if the file is not present. It shouldn't be too hard to do this by using GETATTR and immidiately checking for Err 53 though. I'll have a go tonight.
            Thanks for the reply.
            Chris



            Dave:
            OPEN Shellline FOR BINARY ACCESS READ AS #1
            This still creates the zero length file, if the file with that name does not exist when the call was made. I'm about to try using GETATTR to see if the file exists first.


            Michael:
            LOCAL DD AS DIRDATA
            Is this CC5 only code, or can this be made to work with PBW/8?
            I'm nor sure what you mean be "DIRDATA", I was under the impression that when a variable is declared "AS" a certain type, it had to be a specific data type, such as STRING, INTEGER, WORD, etc.
            I tried it anyway, but it choked in the above line, as I semi-expected.

            Regards,
            Chris

            Comment

            • Mike Doty
              Member
              • Feb 2005
              • 9263

              #7
              DirData is internally defined in PBWIN9 and PB5.
              DIR$ has been improved
              Thanks Michael for showing the code.
              Last edited by Mike Doty; 6 Apr 2009, 08:11 AM.
              Eighth Amendment:
              “Excessive bail shall not be required, nor excessive fines imposed, nor cruel and unusual punishments inflicted.”​

              Comment

              • Mike Doty
                Member
                • Feb 2005
                • 9263

                #8
                DIR$ function

                Purpose
                Return a filename and/or directory entry that matches a file name mask and an optional attribute.
                Syntax
                file$ = DIR$(mask$ [, [ONLY] attribute&, TO DirDataVar])
                file$ = DIR$([NEXT] [TO DirDataVar])

                The DIR$ function may optionally assign the complete directory entry to an appropriate UDT variable if you include the TO clause as a parameter. The complete directory entry contains 318 bytes of data, corresponding to the following TYPE definition. This definition (DIRDATA) is built into PowerBASIC, and need not necessarily be included in your source code.
                TYPE DirData
                ..FileAttributes AS DWORD
                ..CreationTime AS QUAD
                ..LastAccessTime AS QUAD
                ..LastWriteTime AS QUAD
                ..FileSizeHigh AS DWORD
                ..FileSizeLow AS DWORD
                ..Reserved0 AS DWORD
                ..Reserved1 AS DWORD
                ..FileName AS ASCIIZ * 260
                ..ShortName AS ASCIIZ * 14
                END TYPE


                TYPE WIN32_FIND_DATA
                dwFileAttributes AS DWORD
                ftCreationTime AS FILETIME
                ftLastAccessTime AS FILETIME
                ftLastWriteTime AS FILETIME
                nFileSizeHigh AS DWORD
                nFileSizeLow AS DWORD
                dwReserved0 AS DWORD
                dwReserved1 AS DWORD
                cFileName AS ASCIIZ * %MAX_PATH
                cAlternateFileName AS ASCIIZ * 14
                END TYPE
                Last edited by Mike Doty; 6 Apr 2009, 07:39 AM.
                Eighth Amendment:
                “Excessive bail shall not be required, nor excessive fines imposed, nor cruel and unusual punishments inflicted.”​

                Comment

                • Mike Doty
                  Member
                  • Feb 2005
                  • 9263

                  #9
                  Rewrote as SUB because DWORD can't return a negative number to indicate not found in a function.

                  The range is only 0 to 4,294,967,295 bytes.

                  Code:
                  SUB FileSize(BYVAL f AS STRING, TheSize AS DWORD,Found AS LONG)
                    LOCAL FindData AS WIN32_FIND_DATA
                    LOCAL hDir AS LONG
                    hDir = FindFirstFile(BYVAL STRPTR(f), FindData)
                    IF hDir = -1 THEN  
                      TheSize = 0
                      Found =  0
                    ELSE
                      Found = 1
                      FindClose hDir
                      TheSize = FindData.nFileSizeLow
                    END IF
                  END SUB
                  Last edited by Mike Doty; 6 Apr 2009, 01:32 PM. Reason: DWORD can't return a negative number, added Found
                  Eighth Amendment:
                  “Excessive bail shall not be required, nor excessive fines imposed, nor cruel and unusual punishments inflicted.”​

                  Comment

                  • Mike Doty
                    Member
                    • Feb 2005
                    • 9263

                    #10
                    User to user discussions about the PB/Win (formerly PB/DLL) product line. Discussion topics include PowerBASIC Forms, PowerGEN and PowerTree for Windows.
                    Last edited by Mike Doty; 6 Apr 2009, 02:27 PM.
                    Eighth Amendment:
                    “Excessive bail shall not be required, nor excessive fines imposed, nor cruel and unusual punishments inflicted.”​

                    Comment

                    • Mike Doty
                      Member
                      • Feb 2005
                      • 9263

                      #11
                      Code:
                      FUNCTION FileSize(BYVAL f AS STRING) AS QUAD
                        LOCAL FindData AS WIN32_FIND_DATA
                        LOCAL hDir AS LONG
                        hDir = FindFirstFile(BYVAL STRPTR(f), FindData)
                        IF hDir = -1 THEN  'if not found return -1
                          FUNCTION = -1
                        ELSE               'return number of bytes
                          FindClose hDir
                          FUNCTION = MAK(QUAD, FindData.nFileSizeLow , FindData.nFileSizeHigh)
                        END IF
                      END FUNCTION
                      Last edited by Mike Doty; 6 Apr 2009, 02:26 PM. Reason: Tested on a 99 billion-byte file
                      Eighth Amendment:
                      “Excessive bail shall not be required, nor excessive fines imposed, nor cruel and unusual punishments inflicted.”​

                      Comment

                      • Dave Biggs
                        Member
                        • Feb 2001
                        • 3808

                        #12
                        Nice one Mike - That's a keeper!
                        Rgds, Dave

                        Comment

                        • Mike Doty
                          Member
                          • Feb 2005
                          • 9263

                          #13
                          Filesize

                          Does PB have a file size routine?
                          Tested with Windows 7.

                          Code:
                          %MAX_PATH  = 260  ' max. length of full pathname
                          '------------------------------------------------------------------------------
                          TYPE FILETIME
                            dwLowDateTime AS DWORD
                            dwHighDateTime AS DWORD
                          END TYPE
                          '------------------------------------------------------------------------------
                          TYPE WIN32_FIND_DATA
                            dwFileAttributes AS DWORD
                            ftCreationTime AS FILETIME
                            ftLastAccessTime AS FILETIME
                            ftLastWriteTime AS FILETIME
                            nFileSizeHigh AS DWORD
                            nFileSizeLow AS DWORD
                            dwReserved0 AS DWORD
                            dwReserved1 AS DWORD
                            cFileName AS ASCIIZ * %MAX_PATH
                            cAlternateFileName AS ASCIIZ * 14
                          END TYPE
                          '------------------------------------------------------------------------------
                          DECLARE FUNCTION FindFirstFile LIB "KERNEL32.DLL" ALIAS "FindFirstFileA" _
                                  (lpFileName AS ASCIIZ, lpFindFileData AS WIN32_FIND_DATA) AS DWORD
                          '------------------------------------------------------------------------------
                          DECLARE FUNCTION FindClose LIB "KERNEL32.DLL" ALIAS "FindClose" _
                                  (BYVAL hFindFile AS DWORD) AS LONG
                          '------------------------------------------------------------------------------
                          FUNCTION PBMAIN AS LONG
                            ? FORMAT$(FileSize("c:\windows\system32\mrt.exe"),"#,")
                            REM CreateKillTest
                          END FUNCTION
                          '------------------------------------------------------------------------------
                          FUNCTION FileSize(BYVAL sFileName AS STRING) AS QUAD
                            REM Usage:  Bytes = FileSize(sFileName)
                            REM         Returns -1 if not found
                           
                            LOCAL FindData       AS WIN32_FIND_DATA
                            LOCAL hDir           AS LONG
                            LOCAL sInvalidChars  AS STRING
                           
                            'sInvalidChars = "\/:*?""<>|"  'first character may be \
                            hDir = FindFirstFile(BYVAL STRPTR(sFileName), FindData)
                            IF hDir = -1 THEN  'if not found return -53
                              FUNCTION = -53
                            ELSE               'return number of bytes
                              FindClose hDir
                              FUNCTION = MAK(QUAD, FindData.nFileSizeLow , FindData.nFileSizeHigh)
                            END IF
                          END FUNCTION
                          '------------------------------------------------------------------------------
                          FUNCTION CreateKillTest AS LONG
                           
                            'Create and kill a temp file to test filesize routine
                            LOCAL sFile  AS STRING
                            LOCAL qBytes AS QUAD
                            LOCAL hFile  AS LONG
                            sFile = "\junk.tmp" 'creates and deletes this file
                            qBytes = 0          'quad supported
                           
                            'Test
                            hFile = FREEFILE
                            OPEN sFile FOR BINARY AS #hFile
                            IF ERR THEN ? "Unable to open " + sFile + " error" + STR$(ERRCLEAR):EXIT FUNCTION
                            SEEK #hFile, qBytes +1
                            IF ERR THEN ? "Unable to seek to byte" + STR$(qBytes) + " error" + STR$(ERRCLEAR):EXIT FUNCTION
                            SETEOF #hFile
                            IF ERR THEN ? "Unable to SETEOF, error" + STR$(ERRCLEAR):CLOSE #hFile:EXIT FUNCTION
                            ? sFile + " contains " +  FORMAT$(FileSize(sFile),"#,") + " bytes with file open."
                            CLOSE #hFile
                            ? sFile + " contains " +  FORMAT$(FileSize(sFile),"#,") + " bytes with file closed."
                            KILL sFile
                            IF ERR THEN
                              ? "Unable to kill " + sFile + " error" + STR$(ERRCLEAR)
                            ELSE
                              ? "Killed " +sFile
                            END IF
                            #IF %DEF(%PB_CC32)
                               ? "Press any key to exit"
                               WAITKEY$
                            #ENDIF
                          END FUNCTION
                          Eighth Amendment:
                          “Excessive bail shall not be required, nor excessive fines imposed, nor cruel and unusual punishments inflicted.”​

                          Comment

                          • Dale Yarker
                            Member
                            • Mar 2004
                            • 5449

                            #14
                            Other than LOF function? Improved DIR$ can return a UDT containing members FileSizeHigh and FileSizeLow dword members.

                            Cheers,
                            Dale

                            Comment

                            • Michael Mattias
                              Member
                              • Aug 1998
                              • 43447

                              #15
                              " var = FILESIZE(filespec) " sure sounds like a New Feature Suggestion waiting for someone to submit it.
                              Michael Mattias
                              Tal Systems (retired)
                              Port Washington WI USA
                              [email protected]
                              http://www.talsystems.com

                              Comment

                              • Mike Doty
                                Member
                                • Feb 2005
                                • 9263

                                #16
                                No api calls

                                Code:
                                FUNCTION PBFileSize(BYVAL sFile AS STRING) AS QUAD
                                 
                                  LOCAL Udt AS DIRDATA         'DIRDATA built into PowerBASIC
                                  sFile = DIR$ (sfile TO Udt)  'fill structure
                                  [B]DIR$ CLOSE                   'Michael Mattias.  see post below[/B]
                                  IF LEN(sFile) THEN           'file found
                                    FUNCTION = MAK(QUAD, Udt.FileSizeLow , Udt.FileSizeHigh)'make quad
                                  ELSE
                                    FUNCTION = -53             'not found, return error -53
                                  END IF
                                 
                                END FUNCTION
                                 
                                FUNCTION PBMAIN AS LONG
                                 
                                  LOCAL sFile AS STRING
                                  LOCAL qSize AS QUAD
                                 
                                  sFile = "c:\windows\system32\mrt.exe"
                                  qSize = PBFileSize(sFile)
                                  ? USING$("#,",qSize)
                                 
                                END FUNCTION
                                Last edited by Mike Doty; 25 Aug 2010, 11:16 AM.
                                Eighth Amendment:
                                “Excessive bail shall not be required, nor excessive fines imposed, nor cruel and unusual punishments inflicted.”​

                                Comment

                                • Michael Mattias
                                  Member
                                  • Aug 1998
                                  • 43447

                                  #17
                                  You should add a DIR$ CLOSE to that function.

                                  While it won't make a difference in most cases, the open search handle (from DIR$) will prevent you from deleting or renaming the directory elsewhere in your program.

                                  (Any subsequent call to DIR$ (on this thread) will automatically close the original handle, but IMO it's better to just "release what you get" in the procedure).

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

                                  Comment

                                  • Mike Doty
                                    Member
                                    • Feb 2005
                                    • 9263

                                    #18
                                    DIR$ CLOSE added - thank you Michael Mattias

                                    Good catch, thank you!
                                    Modified here and in the source code forum.

                                    PowerBASIC and related source code. Please do not post questions or discussions, just source code.
                                    Eighth Amendment:
                                    “Excessive bail shall not be required, nor excessive fines imposed, nor cruel and unusual punishments inflicted.”​

                                    Comment

                                    • Dave Biggs
                                      Member
                                      • Feb 2001
                                      • 3808

                                      #19
                                      Odd!
                                      This file "C:\Windows\System32\MRT.exe" does appear in Explorer and I can use DIR with it in a CMD window..
                                      Directory of C:\Windows\System32

                                      03/08/2010 11:52 AM 37,437,384 MRT.exe
                                      1 File(s) 37,437,384 bytes
                                      It doesn't show up in the test program though? The message box reports "-53".

                                      I tried using IsFile() against it - again not found.
                                      Other files in the same directory are found both by IsFile() and PBFileSize() - "C:\Windows\System32\MRINFO.exe" for example.

                                      I'm using Win7 with an 'administrator' account and have tried running the test program with the "Run as Adminstrator" option. Tried running in XPMode - same -53 result .
                                      Last edited by Dave Biggs; 25 Aug 2010, 09:00 PM.
                                      Rgds, Dave

                                      Comment

                                      • Mike Doty
                                        Member
                                        • Feb 2005
                                        • 9263

                                        #20
                                        Would you please report what this reports from a CMD window:
                                        ATTRIB c:\windows\system32\mrt.exe

                                        I tested with 32-bit Windows 7 and it works.
                                        I will test with 64-bit Windows 7 in a few minutes.

                                        Not working with 64-bit Windows 7. Investigating.
                                        Last edited by Mike Doty; 25 Aug 2010, 09:20 PM.
                                        Eighth Amendment:
                                        “Excessive bail shall not be required, nor excessive fines imposed, nor cruel and unusual punishments inflicted.”​

                                        Comment

                                        Working...
                                        X