Microsoft KB Archive/100513

From BetaArchive Wiki
Knowledge Base

How to Read a Large File into Memory by Calling API Functions

Article ID: 100513

Article Last Modified on 12/9/2003


  • Microsoft Visual Basic 2.0 Professional Edition
  • Microsoft Visual Basic 3.0 Professional Edition
  • Microsoft Windows for Workgroups 3.1
  • Microsoft Windows for Workgroups 3.11

This article was previously published under Q100513


This article demonstrates how to call Windows API functions to read a file of any size (including a huge file such as a bitmap) into memory and how to write a block of memory (including a huge memory block) out to a file.

The information in this article applies only to Windows version 3.1 or higher because it uses Windows API functions introduced in Windows version 3.1.


Perform the following steps to create a sample program that demonstrates how to read a large file into memory and write that memory back out to a file:

  1. Start Visual Basic or from the File menu, choose New Project (ALT, F, N) if Visual Basic is already running. Form1 is created by default.
  2. From the File menu, choose New Module (ALT, F, M). Module1 is created.
  3. Add the following code to the general-declarations section of Module1:

       ' OpenFile() Structure
       Type OFSTRUCT
          cBytes As String * 1
          fFixedDisk As String * 1
          nErrCode As Integer
          reserved As String * 4
          szPathName As String * 128
       End Type
       ' OpenFile() Flags
       Global Const OF_READ = &H0
       Global Const OF_WRITE = &H1
       Global Const OF_READWRITE = &H2
       Global Const OF_SHARE_COMPAT = &H0
       Global Const OF_SHARE_EXCLUSIVE = &H10
       Global Const OF_SHARE_DENY_WRITE = &H20
       Global Const OF_SHARE_DENY_READ = &H30
       Global Const OF_SHARE_DENY_NONE = &H40
       Global Const OF_PARSE = &H100
       Global Const OF_DELETE = &H200
       Global Const OF_VERIFY = &H400
       Global Const OF_CANCEL = &H800
       Global Const OF_CREATE = &H1000
       Global Const OF_PROMPT = &H2000
       Global Const OF_EXIST = &H4000
       Global Const OF_REOPEN = &H8000
       ' Enter each of the following Declare statements on one, single line:
       Declare Function OpenFile Lib "Kernel" (ByVal lpFilename As
          String, lpReOpenBuff As OFSTRUCT, ByVal wStyle As Integer) As Integer
       Declare Function hRead Lib "kernel" Alias "_hread" (ByVal hFile As
          Integer, lpMem As Any, ByVal lSize As Long) As Long
       Declare Function hWrite Lib "Kernel" Alias "_hwrite" (ByVal hFile
          As Integer, lpMem As Any, ByVal lSize As Long) As Long
       Declare Function lClose Lib "kernel" Alias "_lclose" (ByVal hFile
          As Integer) As Integer
       ' Global Memory Flags
       Global Const GMEM_FIXED = &H0
       Global Const GMEM_MOVEABLE = &H2
       Global Const GMEM_NOCOMPACT = &H10
       Global Const GMEM_NODISCARD = &H20
       Global Const GMEM_ZEROINIT = &H40
       Global Const GMEM_MODIFY = &H80
       Global Const GMEM_DISCARDABLE = &H100
       Global Const GMEM_NOT_BANKED = &H1000
       Global Const GMEM_SHARE = &H2000
       Global Const GMEM_DDESHARE = &H2000
       Global Const GMEM_NOTIFY = &H4000
       Global Const GMEM_LOWER = GMEM_NOT_BANKED
       Global Const GPTR = (GMEM_FIXED Or GMEM_ZEROINIT)
       ' Enter each of the following Declare statements on one, single line:
       Declare Function GlobalAlloc Lib "Kernel" (ByVal wFlags As
           Integer, ByVal dwBytes As Long) As Integer
       Declare Function GlobalLock Lib "Kernel" (ByVal hMem As Integer)
           As Long
       Declare Function GlobalUnlock Lib "Kernel" (ByVal hMem As Integer)
           As Integer
       Declare Function GlobalFree Lib "Kernel" (ByVal hMem As Integer)
           As Integer
  4. Add the following code to the Form_Load event procedure of Form1:

       Sub Form_Load ()
          Dim InpFile As String
          Dim OutFile As String
          Dim hFile As Integer
          Dim fileStruct As OFSTRUCT
          Dim FSize As Long
          Dim BytesRead As Long
          Dim BytesWritten As Long
          Dim hMem As Integer
          Dim lpMem As Long
          Dim r As Integer
          'Insert the name of a bitmap or file that is greater than 64K.
          '256COLOR.BMP is less than 5K in size, however, the routine
          'below still demonstrates how to read and write a file of any
          InpFile = "C:\WINDOWS\256COLOR.BMP"
          OutFile = "C:\WINDOWS\TEST.BMP"
          'Get the size of the file to be read
          FSize = FileLen(InpFile)
          If FSize > 0 Then
             'Allocate a block of memory equal to the size of the input file.
             hMem = GlobalAlloc(GPTR, FSize)
             If hMem <> 0 Then
                lpMem = GlobalLock(hMem)
                'Read the file into memory
                hFile = OpenFile(InpFile, fileStruct, OF_READ Or
                BytesRead = hRead(hFile, ByVal lpMem, FSize)
                MsgBox Format(BytesRead) & " bytes read into memory"
                r = lClose(hFile)
                'Write the file back to disk to verify the file was
                'read correctly
                hFile = OpenFile(OutFile, fileStruct, OF_CREATE Or
                                 OF_WRITE Or OF_SHARE_DENY_NONE)
                BytesWritten = hWrite(hFile, ByVal lpMem, FSize)
                MsgBox Format(BytesWritten) & " bytes written to output file"
                r = lClose(hFile)
                'Free resources
                r = GlobalUnlock(hMem)
                r = GlobalFree(hMem)
                 MsgBox "Not enough memory to store file"
             End If
             MsgBox "Input file is zero bytes in length"
          End If
       End Sub
  5. From the Run menu, choose Start (ALT, R, S) or press F5 to run the program. Form1 will be displayed and the program will end.
  6. Use PaintBrush or some other bitmap editor to open C:\WINDOWS\TEST.BMP to verify that it is the same bitmap as C:\WINDOWS\256COLOR.BMP.

Additional query words: 2.00 3.00

Keywords: KB100513