⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 basbigfiles.bas

📁 a Tiger Hash algorithmn code
💻 BAS
📖 第 1 页 / 共 3 页
字号:
Attribute VB_Name = "basBigFiles"
' ***************************************************************************
'  Module:     basBigFiles.bas
'
'  Purpose:    This module calculates the size of a file.  Can handle
'              file sizes greater than 2gb.
'
' Reference:   Richard Newcombe  22-Jan-2007
'              Getting Past the 2 Gb File Limit
'              http://www.codeguru.com/vb/controls/vb_file/directory/article.php/c12917__1/
'
'              How To Seek Past VBA's 2GB File Limit
'              http://support.microsoft.com/kb/189981
'
'              How To Write Data to a File Using WriteFile API
'              http://support.microsoft.com/kb/165942/EN-US/
'
' Description: The descriptions in this module are excerts from Richard
'              Newcombe's article.
'
'              When working in the IDE, any numbers that are entered are
'              limited to a Long variable type. Actually, as far I've
'              found, the IDE uses Longs for most numeric storage within
'              the projects that you write.
'
'              Okay, so what's the problem with Longs? Well, by definition
'              they are a signed 4-byte variable, in hex &H7FFFFFFF, with a
'              lower limit of -2,147,483,648 and an upper limit of
'              2,147,483,647 (2 Gb). &H80000000 stores the sign of the
'              value. Even when you enter values in Hex, they are stored in
'              a Long.
'
'              Working with random access files, you quite often use a Long
'              to store the filesize and current position, completely
'              unaware that if the file you access is just one byte over
'              the 2 Gb size, you can cause your application to corrupt the
'              file when writing to it.
'
'              Unfortunately, there is no quick fix for this. To get around
'              the problem, you need to write your own file handling
'              module, one that uses windows APIs to open, read, write, and
'              close any file.
'
'              The API's expect the Low and High 32-bit values in unsigned
'              format. Also, the APIs return unsigned values. So, the first
'              thing you have to do is decide on a variable type that you
'              can use to store values higher than 2 Gb. After some serious
'              thought, I decided to use a Currency type (64-bit scaled
'              integer) this gives you a 922,337 gig upper file limit, way
'              bigger that the largest hard drive available today.
'
' ===========================================================================
'    DATE      NAME / eMAIL
'              DESCRIPTION
' -----------  --------------------------------------------------------------
' 22-Jan-2007  Richard Newcombe
'              http://www.codeguru.com/vb/controls/vb_file/directory/article.php/c12917__1/
' 03-Feb-2008  Kenneth Ives  kenaso@tx.rr.com
'              Documented and modified
' ***************************************************************************
Option Explicit

' ********************************************************************
' Constants
' ********************************************************************
  Private Const MODULE_NAME            As String = "basBigFiles"
  Private Const DUMMY_NUMBER           As Long = vbObjectError + 513
  Private Const MAXLONG                As Long = 2147483647
  Private Const FILE_BEGIN             As Long = 0
  Private Const FILE_SHARE_READ        As Long = &H1
  Private Const FILE_SHARE_WRITE       As Long = &H2
  Private Const CREATE_NEW             As Long = 1
  Private Const GENERIC_READ           As Long = &H80000000
  Private Const GENERIC_WRITE          As Long = &H40000000
  Private Const OPEN_EXISTING          As Long = 3
  Private Const OPEN_ALWAYS            As Long = 4
  Private Const INVALID_HANDLE_VALUE   As Long = -1
  Private Const FILE_ATTRIBUTE_NORMAL  As Long = &H80
  
' *****************************************************************************
' API Declares
' *****************************************************************************
  ' The CreateFile function creates or opens the following objects and
  ' returns a handle that can be used to access the object:
  '
  '       Files
  '       pipes
  '       mailslots
  '       communications resources
  '       disk devices (Windows NT only)
  '       consoles
  '       directories (open only)
  Private Declare Function CreateFile Lib "kernel32" Alias "CreateFileA" _
          (ByVal lpFileName As String, ByVal dwDesiredAccess As Long, _
          ByVal dwShareMode As Long, ByVal lpSecurityAttributes As Any, _
          ByVal dwCreationDisposition As Long, ByVal dwFlagsAndAttributes As Long, _
          ByVal hTemplateFile As Long) As Long

  ' CloseHandle invalidates the specified object handle, decrements
  ' the object抯 handle count, and performs object retention checks.
  ' Once the last handle to an object is closed, the object is removed
  ' from the operating system. In other words, closes an open file.
  Private Declare Function CloseHandle Lib "kernel32" _
          (ByVal hFile As Long) As Long

  ' This API is used to set the current position in the open file.
  ' This function is very important because any reads or writes to
  ' the file do not automatically forward the file position.
  Private Declare Function SetFilePointer Lib "kernel32" _
          (ByVal hFile As Long, ByVal lDistanceToMove As Long, _
          lpDistanceToMoveHigh As Long, ByVal dwMoveMethod As Long) As Long

  ' Use SetEndOfFile to set the new end of the file marker. This
  ' function moves the end-of-file position for the specified file
  ' to the current position of the file pointer.
  Private Declare Function SetEndOfFile Lib "kernel32" _
          (ByVal hFile As Long) As Long

  ' This function writes data to a file, starting at the position
  ' indicated by the file pointer. After the write operation has
  ' been completed, the file pointer is adjusted by the number of
  ' bytes written.
  Private Declare Function WriteFile Lib "kernel32" _
          (ByVal hFile As Long, lpBuffer As Any, _
          ByVal nNumberOfBytesToWrite As Long, _
          lpNumberOfBytesWritten As Long, _
          ByVal lpOverlapped As Any) As Long

  ' This function reads data from a file, starting at the position
  ' indicated by the file pointer. After the read operation has
  ' been completed, the file pointer is adjusted by the number of
  ' bytes read.
  Private Declare Function ReadFile Lib "kernel32" _
          (ByVal hFile As Long, lpBuffer As Any, _
          ByVal nNumberOfBytesToRead As Long, _
          lpNumberOfBytesRead As Long, _
          ByVal lpOverlapped As Any) As Long

  ' GetFileSize determines the size of the file. The file size is
  ' given in a 64-bit value that is split into two 32-bit values.
  ' The high-order half is put into the variable passed as
  ' lpFileSizeHigh; the low-order half is returned by the function.
  ' To get the size, you can either put the binary or hexadecimal
  ' values of the two variables side-by-side, or use the formula
  ' filesize = lpFileSizeHigh * 2^32 + return value. If an error
  ' occurs, the function instead returns -1.
  Private Declare Function GetFileSize Lib "kernel32.dll" _
          (ByVal hFile As Long, lpFileSizeHigh As Long) As Long

  ' Forces Windows to flush the write cache.
  Private Declare Function FlushFileBuffers Lib "kernel32" _
          (ByVal hFile As Long) As Long

  ' Retrieves a set of FAT file system attributes for a specified file
  ' or directory. Used here to determine if a path or file exist.
  Private Declare Function GetFileAttributes Lib "kernel32" _
          Alias "GetFileAttributesA" (ByVal lpSpec As String) As Long


' ***************************************************************************
' ***                           Methods                                   ***
' ***************************************************************************

' ***************************************************************************
' Routine:       OpenReadOnly
'
' Description:   Open a file to be used as input.  The file must already
'                exist.  If the file does not exist, an error will occur.
'
' WARNING:       Always make a backup of the files that are to be processed.
'
' Parameters:    strFileName - Fully qualified path and file name
'                hFile - Numeric value designating an open file
'
' Returns:       TRUE - Successfully opened file
'                FALSE - An error occurred while accessing the file
'
' ===========================================================================
'    DATE      NAME / DESCRIPTION
' -----------  --------------------------------------------------------------
' 03-Mar-2008  Kenneth Ives  kenaso@tx.rr.com
'              Wrote routine
' ***************************************************************************
Public Function OpenReadOnly(ByVal strFileName As String, _
                             ByRef hFile As Long) As Boolean

    Const ROUTINE_NAME As String = "OpenReadOnly"

    On Error GoTo OpenReadOnly_Error

    OpenReadOnly = False   ' Preset to bad ending
    
    ' See if the user wants to stop processing
    DoEvents
    If gblnStopProcessing Then
        Exit Function
    End If
    
    ' make sure the file does exist
    If Not FileExists(strFileName) Then
    
        Err.Raise DUMMY_NUMBER, ROUTINE_NAME, _
                  "Cannot find file at this location." & vbCrLf & vbCrLf & _
                  "File:  " & strFileName
    End If

    ' Open a file that is to be used as input (read only).
    hFile = CreateFile(strFileName, _
                       GENERIC_READ, FILE_SHARE_READ, _
                       0&, OPEN_EXISTING, 0&, 0&)
    
    ' error opening the file
    If hFile = INVALID_HANDLE_VALUE Then
        
        Err.Raise DUMMY_NUMBER, ROUTINE_NAME, _
                  "Could not open file." & vbCrLf & vbCrLf & _
                  "File:  " & strFileName
    End If
    
    ' Set the pointer to start at the beginning of the file
    SetFilePointer hFile, 0, 0, FILE_BEGIN
    
    ' See if the user wants to stop processing
    DoEvents
    If gblnStopProcessing Then
        API_CloseFile hFile     ' Verify file handle has been released
    Else
        OpenReadOnly = True
    End If
    
OpenReadOnly_CleanUp:
    On Error GoTo 0
    Exit Function

OpenReadOnly_Error:
    ErrorMsg MODULE_NAME, ROUTINE_NAME, Err.Description
    API_CloseFile hFile     ' Verify file handle has been released
    OpenReadOnly = False
    Resume OpenReadOnly_CleanUp

End Function

' ***************************************************************************
' Routine:       OpenReadWrite
'
' Description:   Open a file to update.  If the file exist, if will be
'                opened.  If the file does not exist, it will be created.
'                Use carefully.  If you open an existing file and something
'                goes wrong, the file may become a zero byte file.  There
'                is no recovery of the data available.  I use this to access
'                a temporary work file only.
'
' WARNING:       Always make a backup of the files that are to be processed.
'
' Parameters:    strFileName - Fully qualified path and file name
'                hFile - Numeric value designating an open file
'
' Returns:       TRUE - Successfully opened file
'                FALSE - An error occurred while accessing the file
'
' ===========================================================================
'    DATE      NAME / DESCRIPTION
' -----------  --------------------------------------------------------------
' 22-Jan-2007  Richard Newcombe
'              Wrote routine
' 03-Mar-2008  Kenneth Ives  kenaso@tx.rr.com
'              Modified and documented
' ***************************************************************************
Public Function OpenReadWrite(ByVal strFileName As String, _
                              ByRef hFile As Long) As Boolean

    Const ROUTINE_NAME As String = "OpenReadWrite"

    On Error GoTo OpenReadWrite_Error

    OpenReadWrite = False  ' Preset to bad ending
    
    ' See if the user wants to stop processing
    DoEvents
    If gblnStopProcessing Then
        Exit Function
    End If
    
    ' Open a file that is to be updated.
    hFile = CreateFile(strFileName, _
                       GENERIC_READ Or GENERIC_WRITE, _
                       FILE_SHARE_READ Or FILE_SHARE_WRITE, _
                       0&, OPEN_ALWAYS, 0&, 0&)
    
    ' error opening the file
    If hFile = INVALID_HANDLE_VALUE Then
        
        Err.Raise DUMMY_NUMBER, ROUTINE_NAME, _
                  "Could not open file." & vbCrLf & vbCrLf & _
                  "File:  " & strFileName
    End If
    
    ' Set the pointer to start at the beginning of the file
    SetFilePointer hFile, 0, 0, FILE_BEGIN
    
    ' See if the user wants to stop processing
    DoEvents
    If gblnStopProcessing Then
        API_CloseFile hFile     ' Verify file handle has been released
    Else
        OpenReadWrite = True
    End If

OpenReadWrite_CleanUp:
    On Error GoTo 0
    Exit Function

OpenReadWrite_Error:
    ErrorMsg MODULE_NAME, ROUTINE_NAME, Err.Description
    API_CloseFile hFile     ' Verify file handle has been released
    OpenReadWrite = False
    Resume OpenReadWrite_CleanUp

End Function

' ***************************************************************************
' Routine:       CalcFileSize
'
' Description:   This routine is used to open a file as read only and
'                calculate it's size.
'
' WARNING:       Always make a backup of the files that are to be processed.
'
' Parameters:    strFileName  - Name of file
'                curFileSize  - Returned file size in bytes
'                strBitsInHex - OPTIONAL - Return the file size calculated
'                               into bits and in hex format without leading
'                               zeroes. Used for calculating a hash.
'
' ===========================================================================
'    DATE      NAME / DESCRIPTION
' -----------  --------------------------------------------------------------
' 22-Jan-2007  Richard Newcombe
'              Wrote routine
' 03-Mar-2008  Kenneth Ives  kenaso@tx.rr.com
'              Modified and documented
' ***************************************************************************
Public Sub CalcFileSize(ByVal strFileName As String, _
                        ByRef curFilesize As Currency, _
               Optional ByRef strBitsInHex As String = "")

    Dim hFile        As Long      ' receives a handle to the file
    Dim lngLowOrder  As Long      ' receive the low-order half of the file size
    Dim lngHighOrder As Long      ' receive the high-order half of the file size
    Dim curHexTemp   As Currency  ' Holding area if greater than 2gb
    
    Const ROUTINE_NAME As String = "CalcFileSize"
    
    On Error GoTo CalcFileSize_Error
    
    ' See if the user wants to stop processing
    DoEvents
    If gblnStopProcessing Then
        Exit Sub
    End If

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -