Results 1 to 11 of 11

Thread: VB6 - Insert & Delete data from a file

Threaded View

  1. #1

    Thread Starter
    PowerPoster
    Join Date
    Feb 2002
    Location
    Canada, Toronto
    Posts
    5,803

    VB6 - Insert & Delete data from a file

    It was asked in one of the threads (here) how to insert data into a file without loosing (overriding) any data, and also how to delete data from a file resulting in a smaller file size.

    The theory is simple, when inserting data, you have to shift the data to the right from the position you plan to insert to, and insert the actual data to that position and for deleting, you have to shift the data to the left until the position of deletion, and then truncate the file.

    Here's an example how to insert data:

    VB Code:
    1. Option Explicit
    2.  
    3. Private Sub Form_Load()
    4.     Dim FF As Integer
    5.    
    6.     ' Create some file as an example for testing...
    7.     FF = FreeFile
    8.     Open "C:\test_insert.txt" For Binary Access Read Write As FF
    9.     Put FF, , "01234567890123456789012345678901234567890123456789012345678901234567890123456789"
    10.     Close FF
    11.    
    12.    
    13.    
    14.     FF = FreeFile
    15.     Open "C:\test_insert.txt" For Binary Access Read Write As FF
    16.    
    17.     ' insert some data into the file
    18.     InsertData FF, "+-----+", 3
    19.    
    20.     Close FF
    21. End Sub
    22.  
    23. Private Sub InsertData(ByVal FileNum As Integer, DataToInsert As String, ByVal InsertPos As Long)
    24.     '
    25.     '  Made by Michael Ciurescu (CVMichael from vbforums.com)
    26.     '  Original thread: [url]http://www.vbforums.com/showthread.php?t=433537[/url]
    27.     '
    28.  
    29.     Const cBuffSize As Long = 262144 ' 256 KBytes
    30.    
    31.     Dim Buffer() As Byte, BuffPos As Long
    32.    
    33.     ' Shift all data to the right
    34.    
    35.     If LOF(FileNum) - InsertPos < cBuffSize Then
    36.         ' we can do it in one copy, we don't need a loop
    37.        
    38.         ' resize the buffer so we don't copy too much (more than file size)
    39.         ReDim Buffer(LOF(FileNum) - InsertPos - 1)
    40.        
    41.         ' copy and paste the data to the new location
    42.         Get FileNum, InsertPos, Buffer
    43.         Put FileNum, InsertPos + Len(DataToInsert), Buffer
    44.     Else
    45.         ' we start from the end of the file
    46.         BuffPos = LOF(FileNum)
    47.        
    48.         ' we HAVE to shift from right to left,
    49.         ' otherwise we override important data
    50.        
    51.         Do Until BuffPos <= InsertPos
    52.             ' substract the buffer size from current position
    53.             BuffPos = BuffPos - cBuffSize
    54.            
    55.             If BuffPos < InsertPos Then
    56.                 ' we reached the last copy
    57.                 ' data passed the InsertPos position, so we have to
    58.                 ' resize the buffer so it does not go over InsertPos
    59.                
    60.                 ReDim Buffer(cBuffSize - (InsertPos - BuffPos) - 1)
    61.                 BuffPos = InsertPos
    62.             Else
    63.                 ReDim Buffer(cBuffSize - 1)
    64.             End If
    65.            
    66.             ' copy and paste the data to the new location
    67.             Get FileNum, BuffPos, Buffer
    68.             Put FileNum, BuffPos + Len(DataToInsert), Buffer
    69.         Loop
    70.     End If
    71.    
    72.     ' Insert the actual data
    73.     Put FileNum, InsertPos, DataToInsert
    74. End Sub
    And here is an example on how to delete data:
    VB Code:
    1. Option Explicit
    2.  
    3. Private Const GENERIC_READ_WRITE As Long = &HC0000000
    4. Private Const OPEN_EXISTING As Long = 3
    5. Private Const FILE_ATTRIBUTE_NORMAL As Long = &H80
    6. Private Const FILE_BEGIN As Long = 0
    7. Private Const NO_ERROR As Long = 0
    8.  
    9. Private Type SECURITY_ATTRIBUTES
    10.     nLength As Long
    11.     lpSecurityDescriptor As Long
    12.     bInheritHandle As Long
    13. End Type
    14.  
    15. Private Declare Function CreateFile Lib "kernel32" Alias "CreateFileA" ( _
    16.      ByVal lpFileName As String, ByVal dwDesiredAccess As Long, _
    17.      ByVal dwShareMode As Long, lpSecurityAttributes As SECURITY_ATTRIBUTES, _
    18.      ByVal dwCreationDisposition As Long, ByVal dwFlagsAndAttributes As Long, _
    19.      ByVal hTemplateFile As Long) As Long
    20. Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
    21. Private Declare Function GetFileSize Lib "kernel32" (ByVal hFile As Long, _
    22.      lpFileSizeHigh As Long) As Long
    23. Private Declare Function SetFilePointer Lib "kernel32" ( _
    24.      ByVal hFile As Long, ByVal lDistanceToMove As Long, _
    25.      lpDistanceToMoveHigh As Long, ByVal dwMoveMethod As Long) As Long
    26. Private Declare Function SetEndOfFile Lib "kernel32" (ByVal hFile As Long) As Long
    27.  
    28. Private Declare Function WriteFile Lib "kernel32" (ByVal hFile As Long, _
    29.      lpBuffer As Any, ByVal nNumberOfBytesToWrite As Long, _
    30.      lpNumberOfBytesWritten As Long, lpOverlapped As Any) As Long
    31. Private Declare Function ReadFile Lib "kernel32" (ByVal hFile As Long, _
    32.      lpBuffer As Any, ByVal nNumberOfBytesToRead As Long, _
    33.      lpNumberOfBytesRead As Long, lpOverlapped As Any) As Long
    34.  
    35. Private Declare Function GetLastError Lib "kernel32" () As Long
    36.  
    37.  
    38. Private Sub DeleteData(ByVal FileName As String, DeletePos As Long, DeleteLength As Long)
    39.     '
    40.     '  Made by Michael Ciurescu (CVMichael from vbforums.com)
    41.     '  Original thread: [url]http://www.vbforums.com/showthread.php?t=433537[/url]
    42.     '
    43.     Const cBuffSize As Long = 262144 ' 256 KBytes
    44.    
    45.     Dim SA As SECURITY_ATTRIBUTES
    46.     Dim FHandle As Long
    47.     Dim FileLen As Double
    48.     Dim Buffer() As Byte, BuffPtr As Long
    49.    
    50.     Dim BytesToRead As Long, BytesRead As Long
    51.     Dim ReadPos As Double, WritePos As Double
    52.    
    53.     ' using API position 0 is the first byte, using VB functions position 1 is first byte
    54.     ' so decrement by one to use the same standard...
    55.     DeletePos = DeletePos - 1
    56.    
    57.     ' open the file
    58.     FHandle = CreateFile(FileName, GENERIC_READ_WRITE, 0, SA, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0)
    59.    
    60.     ' get file size
    61.     FileLen = FileSizeDouble(FHandle)
    62.    
    63.     ' alocate memory
    64.     ReDim Buffer(cBuffSize - 1)
    65.    
    66.     ' get memory pointer
    67.     BuffPtr = VarPtr(Buffer(0))
    68.    
    69.     ' calculate read & write positions
    70.     WritePos = DeletePos
    71.     ReadPos = WritePos + DeleteLength
    72.    
    73.     ' shift the data to left
    74.    
    75.     Do Until ReadPos >= FileLen
    76.         ' calculate how much data to read/write
    77.         BytesToRead = dblMIN(cBuffSize, FileLen - ReadPos)
    78.        
    79.         ' copy and paste the data to the new location
    80.         SeekPosDouble FHandle, ReadPos
    81.         ReadFile FHandle, ByVal BuffPtr, BytesToRead, BytesRead, ByVal 0&
    82.        
    83.         SeekPosDouble FHandle, WritePos
    84.         WriteFile FHandle, ByVal BuffPtr, BytesRead, BytesRead, ByVal 0&
    85.        
    86.         WritePos = WritePos + BytesRead
    87.         ReadPos = WritePos + DeleteLength
    88.     Loop
    89.    
    90.     If WritePos < FileLen Then
    91.         ' Seek to where we need to truncate the file
    92.         SeekPosDouble FHandle, WritePos
    93.        
    94.         ' truncate the file
    95.         SetEndOfFile FHandle
    96.     End If
    97.    
    98.     Erase Buffer
    99.     If FHandle <> 0 Then CloseHandle FHandle
    100. End Sub
    101.  
    102. Private Function dblMIN(ByVal V1 As Double, ByVal V2 As Double) As Double
    103.     If V1 < V2 Then
    104.         dblMIN = V1
    105.     Else
    106.         dblMIN = V2
    107.     End If
    108. End Function
    109.  
    110. Private Function SeekPosDouble(ByVal FHandle As Long, ByVal NewPos As Double) As Boolean
    111.     Dim SizeLow As Long, SizeHigh As Long
    112.    
    113.     SizeLow = DoubleToLongs(NewPos, SizeHigh)
    114.    
    115.     SeekPosDouble = SeekPos(FHandle, SizeLow, SizeHigh)
    116. End Function
    117.  
    118. Private Function SeekPos(ByVal FHandle As Long, ByVal NewPos As Long, _
    119.                                    Optional ByVal PosHigh As Long = 0) As Boolean
    120.     Dim Ret As Long, dwError As Long
    121.    
    122.     Ret = SetFilePointer(FHandle, NewPos, PosHigh, FILE_BEGIN)
    123.    
    124.     If Ret = -1 Then
    125.         dwError = GetLastError
    126.         If dwError = NO_ERROR Then SeekPos = True
    127.     Else
    128.         SeekPos = True
    129.     End If
    130. End Function
    131.  
    132. Private Function FileSizeDouble(ByVal FHandle As Long) As Double
    133.     Dim SizeLow As Long, SizeHigh As Long
    134.    
    135.     If FHandle <> 0 Then SizeLow = GetFileSize(FHandle, SizeHigh)
    136.    
    137.     FileSizeDouble = CDbl(SizeHigh) * (2 ^ 32) + LongToDouble(SizeLow)
    138. End Function
    139.  
    140. Private Function LongToDouble(ByVal Lng As Long) As Double
    141.     If Lng And &H80000000 = 0 Then
    142.         LongToDouble = CDbl(Lng)
    143.     Else
    144.         LongToDouble = (Lng Xor &H80000000) + (2 ^ 31)
    145.     End If
    146. End Function
    147.  
    148. Private Function DoubleToLongs(ByVal Dbl As Double, ByRef SizeHigh As Long) As Long
    149.     Dim SizeLowDbl As Double
    150.    
    151.     SizeHigh = Fix(Dbl / 4294967296#)
    152.     SizeLowDbl = Dbl - SizeHigh * 4294967296#
    153.    
    154.     If SizeLowDbl > 2147483647 Then
    155.         DoubleToLongs = CLng(SizeLowDbl - 2147483648#) Xor &H80000000
    156.     Else
    157.         DoubleToLongs = SizeLowDbl
    158.     End If
    159. End Function
    160.  
    161. Private Sub Form_Load()
    162.     Dim FF As Integer
    163.    
    164.     ' Create some file as an example for testing...
    165.     FF = FreeFile
    166.     Open "C:\test_delete.txt" For Binary Access Read Write As FF
    167.     Put FF, , "01234567890123456789012345678901234567890123456789012345678901234567890123456789"
    168.     Close FF
    169.    
    170.     ' delete 2 bytes from the 3'rd position
    171.     ' it should decrease the file size by 2 bytes
    172.     DeleteData "C:\test_delete.txt", 3, 2
    173. End Sub
    Since I have to use API to truncate the file, I decided to write the whole thing in API...
    Last edited by CVMichael; Nov 27th, 2006 at 09:21 AM.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width