Results 1 to 13 of 13

Thread: [RESOLVED] Flush File Buffer on Binary Save

  1. #1

    Thread Starter
    Frenzied Member
    Join Date
    Dec 2012
    Posts
    1,470

    Resolved [RESOLVED] Flush File Buffer on Binary Save

    Ran into a problem when saving a text file that had been shortened. I use the Binary mode with a "Put #" statement to eliminate saving the text length. If after editing the text, the text is longer or the same length as the original text, the "Put #" uses the correct buffer size. But if the text is shorter than original, the file buffer retains the original text at the end of the buffer.

    I could Kill the original file, but if a problem is encountered with saving the text, the contents would be lost. So I came up with this work around.
    Code:
        If Len(Dir(m_Filename)) Then 'File already exists
            If Len(m_sText) < FileLen(m_Filename) Then
                'Text to save is shorter than file length
                TmpName = m_Filename
                N% = InStrRev(TmpName, ".")
                If N% Then TmpName = Left$(TmpName, N%) & "bak"
                Name m_Filename As TmpName
            End If
        End If
        ' Open the file and write out the text to it.
        FileNum = OpenFile(m_Filename, 5, 0, 80)
        If FileNum > 0 Then
            Put #FileNum, , m_sText
            Close FileNum
        End If
        If Len(TmpName) Then Kill TmpName
    Is there a better/shorter way to accomplish this?

    J.A. Coutts

  2. #2
    Hyperactive Member
    Join Date
    Aug 2011
    Location
    Palm Coast, FL
    Posts
    416

    Re: Flush File Buffer on Binary Save

    Not sure of the pure VB solution to that but you can use the SetEndOfFile Win32 API to change the file to new, smaller size.

  3. #3
    PowerPoster
    Join Date
    Feb 2006
    Posts
    24,482

    Re: Flush File Buffer on Binary Save

    Just write a new file after killing the old one.

    When a special case demands it you can write a new file using a temporary name. Then on success rename the old file and new file and finally remove the old file.

  4. #4
    Fanatic Member
    Join Date
    Aug 2016
    Posts
    673

    Re: Flush File Buffer on Binary Save

    Quote Originally Posted by dilettante View Post
    Just write a new file after killing the old one.

    When a special case demands it you can write a new file using a temporary name. Then on success rename the old file and new file and finally remove the old file.
    Code:
    Private Sub TruncateFile(ByRef fileName As String, ByVal Size As Long)
        Dim hFile As Long
        
        ' Get a handle for the file
        hFile = CreateFileW(StrPtr(fileName), GENERIC_WRITE, FILE_SHARE_READ Or FILE_SHARE_WRITE, ByVal 0&, OPEN_EXISTING, 0&, 0&)
        
        ' Seek the location to then new size
        SetFilePointer hFile, Size, 0&, FILE_BEGIN
        
        ' Set the end of file there and close the file
        SetEndOfFile hFile
        CloseHandle hFile
    
    End Sub

  5. #5
    PowerPoster wqweto's Avatar
    Join Date
    May 2011
    Location
    Sofia, Bulgaria
    Posts
    5,120

    Re: Flush File Buffer on Binary Save

    Back in the older DOS days there was no SetEndOfFile on int 21h file handling entry-points at all. The trick was to seek to the position that the file has to be truncated at, and to write zero bytes long chunk.

    Anyone care to check if Put #FileNum, , vbNullString or equivalent empty byte array does the same in VB6 perhaps?

    Edit: Not working, just tested this.
    thinBasic Code:
    1. Private Sub TruncateFile(ByRef fileName As String, ByVal Size As Long)
    2.     Dim nFile           As Integer
    3.     Dim baEmpty()       As Byte
    4.    
    5.     nFile = FreeFile
    6.     Open fileName For Binary Access Write Shared As nFile
    7.     Seek nFile, Size + 1
    8.     baEmpty = vbNullString
    9.     Put nFile, , baEmpty
    10.     Close nFile
    11. End Sub
    cheers,
    </wqw>

  6. #6
    Fanatic Member
    Join Date
    Aug 2016
    Posts
    673

    Re: Flush File Buffer on Binary Save

    Quote Originally Posted by wqweto View Post
    Back in the older DOS days there was no SetEndOfFile on int 21h file handling entry-points at all. The trick was to seek to the position that the file has to be truncated at, and to write zero bytes long chunk.

    Anyone care to check if Put #FileNum, , vbNullString or equivalent empty byte array does the same in VB6 perhaps?

    cheers,
    </wqw>
    Patching the program may change the source file size

  7. #7

    Thread Starter
    Frenzied Member
    Join Date
    Dec 2012
    Posts
    1,470

    Re: Flush File Buffer on Binary Save

    Quote Originally Posted by wqweto View Post
    Back in the older DOS days there was no SetEndOfFile on int 21h file handling entry-points at all. The trick was to seek to the position that the file has to be truncated at, and to write zero bytes long chunk.

    Anyone care to check if Put #FileNum, , vbNullString or equivalent empty byte array does the same in VB6 perhaps?

    Edit: Not working, just tested this.

    cheers,
    </wqw>
    This worked for me.
    Code:
        Private Sub TruncateFile(ByRef fileName As String, ByVal Size As Long)
            Dim nFile           As Integer
            Dim baEmpty       As Byte
            
            nFile = FreeFile
            Open fileName For Binary Access Write Shared As nFile
            Seek nFile, Size + 1
            baEmpty = 0
            Put nFile, , baEmpty
            Close nFile
        End Sub
    J.A Coutts

  8. #8
    PowerPoster wqweto's Avatar
    Join Date
    May 2011
    Location
    Sofia, Bulgaria
    Posts
    5,120

    Re: Flush File Buffer on Binary Save

    No, it's not. This just writes NUL character at Size position.

    Did you actually check the truncated file size in Explorer or similar? It's not changed.

    cheers,
    </wqw>

  9. #9

    Thread Starter
    Frenzied Member
    Join Date
    Dec 2012
    Posts
    1,470

    Re: Flush File Buffer on Binary Save

    Quote Originally Posted by wqweto View Post
    No, it's not. This just writes NUL character at Size position.

    Did you actually check the truncated file size in Explorer or similar? It's not changed.

    cheers,
    </wqw>
    It is just used to shorten the file buffer. Because there could be other changes made, the file has to be saved as normal.
    Code:
        If Len(Dir(m_Filename)) Then 'File already exists
            If Len(m_sText) < FileLen(m_Filename) Then TruncateFile 'Shorten File buffer
        End If
        ' Open the file and write out the text to it.
        FileNum = OpenFile(m_Filename, 5, 0, 80)
        If FileNum > 0 Then
            Put #FileNum, , m_sText
            Close FileNum
        End If
    J.A. Coutts

    Edit: I have to qualify this, as it only appears to solve the problem. Because I placed a null character in the buffer at the correct place, when the data is read into the string, it truncates the string. It doesn't actually change the fie size.
    Last edited by couttsj; Jun 17th, 2018 at 10:19 AM.

  10. #10

    Thread Starter
    Frenzied Member
    Join Date
    Dec 2012
    Posts
    1,470

    Re: Flush File Buffer on Binary Save

    Looks like I will have to go back to my original work around.

    J.A. Coutts

  11. #11
    Fanatic Member
    Join Date
    Aug 2016
    Posts
    673

    Re: Flush File Buffer on Binary Save

    Quote Originally Posted by couttsj View Post
    Looks like I will have to go back to my original work around.

    J.A. Coutts

    Just write a new file after killing the old one.

  12. #12
    Frenzied Member VanGoghGaming's Avatar
    Join Date
    Jan 2020
    Location
    Eve Online - Mining, Missions & Market Trading!
    Posts
    1,318

    Resolved Re: [RESOLVED] Flush File Buffer on Binary Save

    I was confronted with the same problem recently and I ended up using the following workaround just BEFORE writing to the file in "Binary" mode:
    Code:
    Open sFileName For Output Access Write as #FileNum: Close #FileNum ' ensures the old file contents are removed prior to writing new data with "Put"

  13. #13
    PowerPoster wqweto's Avatar
    Join Date
    May 2011
    Location
    Sofia, Bulgaria
    Posts
    5,120

    Re: [RESOLVED] Flush File Buffer on Binary Save

    Open FileName For Output is implemented with CreateFile API using CREATE_ALWAYS flag most probably.

    cheers,
    </wqw>

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