Jump to content

Writing binary to a file


Go to solution Solved by Musashi,

Recommended Posts

Hello all!

I am trying to write binary data to a file, yet all my tries give me text. I open the file with the binary flag but numbers are represented as text. I've checked in a hex editor and 0 is written as 00110000 which equals to dec 48 thus giving the ansi character code of 0 which is clearly not ideal.

I have the binary flag enabled (16) but data is not written as binary.

I've even tried adding in the StringToBinary function but it didn't help, at this point I just can't see what is wrong with my code.

Local $tmpFile = $tmpPath & "\fdnTmp.bin"
    Local $hTmpFile = FileOpen($tmpFile, 2 + 16)
    FileWrite($hTmpFile, StringToBinary($LogIndex & ";" & $InfoCount & ";" & $warningCount & ";" & $errorCount))
    FileClose($hTmpFile)
    FileSetAttrib($tmpFile, "+HT")

Any help would be much appreciated!

Cheers!

Edited by 66Gramms
Link to comment
Share on other sites

Nothing changed. Also it seems like the overwrite flag is not working either. If the file is there it won't write to it, I have to delete it manually, then it is being rewritten. But if the file is there it won't get overwritten.

Link to comment
Share on other sites

58 minutes ago, JockoDundee said:

Use Binary() instead of StringToBinary().

Thanks to @JockoDundee for this tip. 

Both these methods work, giving identical output. The second one unfortunately extends the output file on each invocation so you first need to delete it if you don't want it to grow.

 

$sBuf = ''
For $i = 0 To 255
  $sBuf &= Chr($i)
Next
$hHandle = FileOpen(@ScriptDir & "\BinDatH.bin", 2 + 512)
FileWrite($hHandle, Binary($sBuf))
FileClose($hHandle)

FileDelete(@ScriptDir & "\BinDat.bin")
$bBuf = StringToBinary($sBuf)
FileWrite(@ScriptDir & "\BinDat.bin", Binary($bBuf))

 

Edited by pseakins
1 typo. 2 file extend is documented feature

Phil Seakins

Link to comment
Share on other sites

I've checked with the _WinAPI_FileInUse as recommended but it returns 0 just before I open the file for writing. I've tried moving the file from my user folder to C:\someNewFolder\file.bin but still overwriting won't work.

Binary and StringToBinary both return a correct hexadecimal value when displayed with a messagebox, yet in the file numbers are still written as pure text.

 

Link to comment
Share on other sites

  • Developers

So what is the returncode/error for the FileWrite() as I don't see a check for that in your code?

SciTE4AutoIt3 Full installer Download page   - Beta files       Read before posting     How to post scriptsource   Forum etiquette  Forum Rules 
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Link to comment
Share on other sites

  • Solution
3 hours ago, 66Gramms said:

... except for one which is when opening it with the overwrite flag ...

What happens if you run the following example ? Does the overwrite fail or not ?

#include <FileConstants.au3>
#include <MsgBoxConstants.au3>

; fake data, since real values were not specified :-)
Local $sInfo     = "@Logdata", $LogIndex = 16, $InfoCount = 127, $WarningCount = 255, $ErrorCount = 1024
Local $hFileOpen
Local $sFilePath = @ScriptDir & "\fdnTmp.bin"
Local $sData     = $sInfo & ";" & $LogIndex & ";" & $InfoCount & ";" & $WarningCount & ";" & $ErrorCount
Local $dBinData  = Binary($sData)
MsgBox(BitOR($MB_SYSTEMMODAL, $MB_ICONINFORMATION), "Output :", $sData & @CRLF & $dBinData & @CRLF & "IsBinary = " & IsBinary($dBinData))


; Delete file (in case it exists) :
Local $iFileExists = FileExists($sFilePath)
If $iFileExists Then
    MsgBox($MB_SYSTEMMODAL, "", "The file exists and will be deleted." & @CRLF & "FileExist returned: " & $iFileExists)
Else
    MsgBox($MB_SYSTEMMODAL, "", "The file doesn't exist." & @CRLF & "FileExist returned: " & $iFileExists)
EndIf
FileDelete($sFilePath)


; Create a testfile -> @ScriptDir & "\fdnTmp.bin"
$hFileOpen = FileOpen($sFilePath, $FO_OVERWRITE)
If $hFileOpen = -1 Then Exit MsgBox(BitOR($MB_SYSTEMMODAL, $MB_ICONERROR), "", "1. ERROR : FileOpen()")
FileWrite($hFileOpen, "Testfile")
If @error Then MsgBox(BitOR($MB_SYSTEMMODAL, $MB_ICONERROR), "", "1. ERROR : FileWrite()")
FileClose($hFileOpen)


; Overwrite existing file :
$hFileOpen = FileOpen($sFilePath, BitOR($FO_BINARY, $FO_OVERWRITE))
If $hFileOpen = -1 Then Exit MsgBox(BitOR($MB_SYSTEMMODAL, $MB_ICONERROR), "", "2. ERROR : FileOpen()")
FileWrite($hFileOpen, $dBinData)
If @error Then MsgBox(BitOR($MB_SYSTEMMODAL, $MB_ICONERROR), "", "2. ERROR : FileWrite()")
FileClose($hFileOpen)

 

Musashi-C64.png

"In the beginning the Universe was created. This has made a lot of people very angry and been widely regarded as a bad move."

Link to comment
Share on other sites

13 hours ago, 66Gramms said:

Nothing changed. Also it seems like the overwrite flag is not working either. If the file is there it won't write to it, I have to delete it manually, then it is being rewritten. But if the file is there it won't get overwritten.

The problem with it not being binary, in the way you want it, is simple:

When you concatenate a binary variable with a string it becomes a string again, then when Binary runs on it, it gets encoded as text.

This line is the problem:

FileWrite($hTmpFile, Binary($LogIndex & ";" & $InfoCount & ";" & $warningCount & ";" & $errorCount))

If instead you try:

FileWrite($hTmpFile, Binary($LogIndex))

Assuming that $LogIndex is a Integer, then you will file a four-byte file containing a binary written integer.

As for the file overwrite problems, your code works fine with me, and either creates or overwrites as appropriate.  However I do not know the value of your $tmpPath variable, maybe there is a directory permission problem?

Code hard, but don’t hard code...

Link to comment
Share on other sites

You seem to be right, I didn't think of that this will be concatenated to a string, I guess I'll have to write all variables one after another.

On 7/23/2021 at 4:24 PM, Musashi said:

What happens if you run the following example ? Does the overwrite fail or not ?

#include <FileConstants.au3>
#include <MsgBoxConstants.au3>

; fake data, since real values were not specified :-)
Local $sInfo     = "@Logdata", $LogIndex = 16, $InfoCount = 127, $WarningCount = 255, $ErrorCount = 1024
Local $hFileOpen
Local $sFilePath = @ScriptDir & "\fdnTmp.bin"
Local $sData     = $sInfo & ";" & $LogIndex & ";" & $InfoCount & ";" & $WarningCount & ";" & $ErrorCount
Local $dBinData  = Binary($sData)
MsgBox(BitOR($MB_SYSTEMMODAL, $MB_ICONINFORMATION), "Output :", $sData & @CRLF & $dBinData & @CRLF & "IsBinary = " & IsBinary($dBinData))


; Delete file (in case it exists) :
Local $iFileExists = FileExists($sFilePath)
If $iFileExists Then
    MsgBox($MB_SYSTEMMODAL, "", "The file exists and will be deleted." & @CRLF & "FileExist returned: " & $iFileExists)
Else
    MsgBox($MB_SYSTEMMODAL, "", "The file doesn't exist." & @CRLF & "FileExist returned: " & $iFileExists)
EndIf
FileDelete($sFilePath)


; Create a testfile -> @ScriptDir & "\fdnTmp.bin"
$hFileOpen = FileOpen($sFilePath, $FO_OVERWRITE)
If $hFileOpen = -1 Then Exit MsgBox(BitOR($MB_SYSTEMMODAL, $MB_ICONERROR), "", "1. ERROR : FileOpen()")
FileWrite($hFileOpen, "Testfile")
If @error Then MsgBox(BitOR($MB_SYSTEMMODAL, $MB_ICONERROR), "", "1. ERROR : FileWrite()")
FileClose($hFileOpen)


; Overwrite existing file :
$hFileOpen = FileOpen($sFilePath, BitOR($FO_BINARY, $FO_OVERWRITE))
If $hFileOpen = -1 Then Exit MsgBox(BitOR($MB_SYSTEMMODAL, $MB_ICONERROR), "", "2. ERROR : FileOpen()")
FileWrite($hFileOpen, $dBinData)
If @error Then MsgBox(BitOR($MB_SYSTEMMODAL, $MB_ICONERROR), "", "2. ERROR : FileWrite()")
FileClose($hFileOpen)

 

I thought about deleting the file manually as creating it worked, this solves the problem, though I wanted to avoid if possible. It worked, so I'll go with this solution. I wish I could mark both of your posts as solution.

Thank you for your help!

 

Edited by 66Gramms
Link to comment
Share on other sites

28 minutes ago, 66Gramms said:

I guess I'll have to write all variables one after another.

There's another way to do it without writing all the variables one after another - you create a struct that contains the datatypes and the order of the vars, then assign them, then write the struct.

Take a look here at @Nine's struct based solution to a slightly different problem, and if its not clear how to apply it, let us know.

 

Code hard, but don’t hard code...

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...