puting floats into a Binary file

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • swordman
    New Member
    • Aug 2007
    • 3

    #1

    puting floats into a Binary file

    I'me new here, so I wish to say HELLO to all members.
    I'm quite new to python, but I manage to do something using python in blender.
    Now, I need to save in a binary file raw data (specificaly blocks of 3 float), for a later use. How can I manage this? i tried the write() function, but it need the conversion to string, I need the value! Thanks all!
  • bartonc
    Recognized Expert Expert
    • Sep 2006
    • 6478

    #2
    You may find a suitable solution here.

    Comment

    • swordman
      New Member
      • Aug 2007
      • 3

      #3
      Thanks for the reply.
      I've already take alook at that thread, but, as far I can understand it, they are reading from a file. I need to write the data in it.
      I suppose thet I've to use the struct.pack in some way, but I cant figure out how

      Comment

      • dshimer
        Recognized Expert New Member
        • Dec 2006
        • 136

        #4
        I use the struct functions all the time for this very thing, though rarely see them talked about here. Probably because I'm missing out on an easy way to do things. I did though write a script as an example for my blog. It may or may not be useful but, goes like this.

        [CODE=python]
        print 'testbinary.py modified 11:00 PM 7/10/2007'
        '''
        Copyright 2007 Dennis Shimer
        Vr Mapping copyright Cardinal Systems, LLC
        No warranties as to safety or usability expressed or implied.
        Free to use, copy, modify, distribute with author credit.

        just a lesson in binary data. Either run from a command line 3 times like
        python testbinary.py
        or open or paste into pyedi and execute 3 times.
        '''

        import os,struct
        # We'll use os to test for the existence of the file, an struct to
        # interact with the binary data.

        FormatString='1 0sddi'
        '''
        The format string tells several parts of the program what we are working
        with in regards to binary data. The format string listed above represents
        a 10 character string, 2 double precision real numbers, and an integer.
        Same as before but I added the int to show by example. Note that it is
        just a string with letters representing different kinds of data.
        '''

        ParFileName='te stbinary.par'
        # The file by this name will show up in the directory the script is run in.

        print 'Bytes occupied by binary data',struct.ca lcsize(FormatSt ring),'\n\n'
        '''
        Sometimes you need to know how many bytes to read from a file in order
        to get one set of data when multiple sets exist, a good example goes
        back to the coordinate file mentioned earlier. In order to read and process
        one point at a time you can only read the necessary bytes. the calcsize
        method in struct will read a format string and tell how many bytes are
        represented. You can go into a python interpreter, import struct then
        evaluate some single item format strings like the following for a
        float, a double, an int, and a 1 character string.
        >>> struct.calcsize ('f')
        4
        >>> struct.calcsize ('d')
        8
        >>> struct.calcsize ('i')
        4
        >>> struct.calcsize ('s')
        1
        '''

        if not os.path.isfile( ParFileName): # If the file doesn't exist.
        ParFile=open(Pa rFileName,'wb')
        # Then open it in write (create or erase) mode with a binary modifier

        BinaryData=stru ct.pack(FormatS tring,'Word',.2 ,.0,0)
        '''
        The pack method in the struct module uses the format string to process
        the data that comes next into the bytes which represent them in binary
        form. It is important that the amount and type of data following the
        format string match, notice I am passing in a string (less than 10
        characters allowed, 2 real numbers and an integer.
        '''

        ParFile.write(B inaryData)
        ParFile.close()
        # We have a binary file and binary data so just and write and close it.

        print 'Program run with no existing file'
        print 'Data set to defaults.'
        print 'testbinary.par should now exist.'
        else:
        ParFile=open(Pa rFileName,'r+b' )
        # If it does exist open for reading + writing with binary modifier.

        BinaryData=ParF ile.read()
        '''
        This time since the file exists we are going to get the binary data
        right out of the file with a read. Since we want the whole file there
        is no reason to use calcsize to tell it how many bytes to read.
        '''

        DataList=struct .unpack(FormatS tring,BinaryDat a)
        # Going the other direction, lets use unpack to use the format string
        # to convert the binary data into a list of values.

        print 'Data from file, note it is a list\n ',DataList
        # and print the list.

        ParFile.seek(0, 0)
        '''
        Now assuming that there are new values that need to be used to update
        the parameter file. The first thing we need to do is go back to the
        beginning of the file, read up on seek, but this basically moves you
        0 bytes from the beginning. If in the coordinate file example I had a
        data structure that require 24 bytes and wanted to get the 3rd value
        from the file I could to the 48th byte and read 24. This way you can
        read, write, and overwrite data in place within a file.
        '''

        print 'File position after seek ',ParFile.tell( )
        # Every open file has a tell method which gives the current position.

        BinaryData=stru ct.pack(FormatS tring,'Updated' ,1,2,3)
        ParFile.write(B inaryData)
        # Same idea as above, just using the changed data (wherever it came from)

        if DataList[0].split('\x00')[0]=='Updated':
        print 'You have seen it all.'
        print 'Remove testbinary.par to start over'
        '''
        There may be a better way to convert this 10 character string to
        what you normally think of as a string, but it comes back padded
        with the 0 bytes and this works simply enough. Think of it this
        way 'Updated\x00\x0 0\x00' has 3 extra bytes, if you split on that
        character you get back ['Updated', '', '', ''] of which 'Updated'
        is the first or [0] element. Ugly but I've never really look into
        a better way.
        '''

        else:
        print 'Program run with an existing file'
        print 'Data was updated run again to see change'
        # 2nd run string doesn't equal 'Updated' so print appropriate message.

        ParFile.close()
        # Good form to explicitely close files.

        [/CODE]

        Originally posted by swordman
        Thanks for the reply.
        I've already take alook at that thread, but, as far I can understand it, they are reading from a file. I need to write the data in it.
        I suppose thet I've to use the struct.pack in some way, but I cant figure out how
        Last edited by bartonc; Aug 24 '07, 12:58 AM. Reason: Added =python to code tags

        Comment

        • swordman
          New Member
          • Aug 2007
          • 3

          #5
          Thanks a lot! It is exactly what I'm looking for! And a very good explanation too.
          Thanks again.

          Comment

          Working...