-
Jun 14th, 2018, 11:08 AM
#1
[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
-
Jun 14th, 2018, 11:55 AM
#2
Hyperactive Member
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.
-
Jun 14th, 2018, 04:44 PM
#3
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.
-
Jun 15th, 2018, 04:46 AM
#4
Fanatic Member
Re: Flush File Buffer on Binary Save
Originally Posted by dilettante
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
-
Jun 15th, 2018, 05:07 AM
#5
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:
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 = vbNullString
Put nFile, , baEmpty
Close nFile
End Sub
cheers,
</wqw>
Last edited by wqweto; Jun 15th, 2018 at 07:47 AM.
-
Jun 15th, 2018, 05:13 AM
#6
Fanatic Member
Re: Flush File Buffer on Binary Save
Originally Posted by wqweto
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
-
Jun 15th, 2018, 11:18 AM
#7
Re: Flush File Buffer on Binary Save
Originally Posted by wqweto
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
-
Jun 16th, 2018, 03:16 AM
#8
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>
-
Jun 16th, 2018, 08:29 AM
#9
Re: Flush File Buffer on Binary Save
Originally Posted by wqweto
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.
-
Jun 19th, 2018, 05:22 PM
#10
Re: Flush File Buffer on Binary Save
Looks like I will have to go back to my original work around.
J.A. Coutts
-
Jun 19th, 2018, 06:21 PM
#11
Fanatic Member
Re: Flush File Buffer on Binary Save
Originally Posted by couttsj
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.
-
Apr 19th, 2021, 11:15 PM
#12
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"
-
Apr 20th, 2021, 01:04 AM
#13
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
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|