Tengo una cadena (que podría ser un entero también) en Python y quiero escribir en un archivo. Contiene sólo unos y ceros quiero que el patrón de unos y ceros para ser escrito a un archivo. Quiero escribir el binario directamente porque necesito almacenar una gran cantidad de datos, pero sólo ciertos valores. No veo necesidad de ocupar el espacio de utilización de ocho bits por valor cuando yo sólo necesito tres.

Por ejemplo. Digamos que yo fuera a escribir la cadena binaria "01100010" a un archivo. Si me los abre en un editor de texto que diría b (01100010 es el código ascii para el b). No debe confundirse, sin embargo. Yo no quiero escribir los códigos ascii, el ejemplo fue para indicar que quiero escribir directamente bytes en el archivo.


Aclaración:

Mi cadena se ve algo como esto:

binary_string = "001011010110000010010"

No está hecho de de los códigos binarios de números o caracteres. Contiene datos relativos sólo a mi programa.

OriginalEl autor KFox | 2013-06-02

5 Comentarios

  1. 8

    A escribir una cadena de texto que se puede usar el archivo de la .write método. Para escribir un número entero, usted tendrá que utilizar el struct módulo

    import struct
    
    #...
    with open('file.dat', 'wb') as f:
        if isinstance(value, int):
            f.write(struct.pack('i', value)) # write an int
        elif isinstance(value, str):
            f.write(value) # write a string
        else:
            raise TypeError('Can only write str or int')

    Sin embargo, la representación de int y string son diferentes, puede que con el uso de la bin función en lugar de convertirlo en una cadena de 0s y 1s

    >>> bin(7)
    '0b111'
    >>> bin(7)[2:] #cut off the 0b
    '111'

    pero tal vez la mejor manera de manejar todos estos ints es decidir sobre un ancho fijo para las cadenas binarias en el archivo y convertirlos así:

    >>> x = 7
    >>> '{0:032b}'.format(x) #32 character wide binary number with '0' as filler
    '00000000000000000000000000000111'
    Esto no es lo que quiero. He editado la pregunta para mostrar más específicamente, ¿qué tengo que hacer.
    así que estás diciendo que quieres una función que: dado un int o un str de 0s y 1s, desea escribir a un archivo, como una representación binaria de un int en lugar de una cadena de 0/1 caracteres. No estoy seguro de lo que quieres decir con «cuando yo sólo necesita 3.» ¿quiere decir que sólo utiliza 24 bits en el valor más grande?
    Lo sentimos, no fue más claro. He encontrado la respuesta ahora de todos modos. Gracias por tu respuesta, aunque.

    OriginalEl autor Ryan Haining

  2. 4

    Quiero que el patrón de unos y ceros para ser escrito a un archivo.

    Si quieres decir que te gustaría escribir un flujo de bits a partir de una cadena en un archivo, tendrás algo como esto…

    from cStringIO import StringIO
    
    s = "001011010110000010010"
    sio = StringIO(s)
    
    f = open('outfile', 'wb')
    
    while 1:
        # Grab the next 8 bits
        b = sio.read(8)
    
        # Bail if we hit EOF
        if not b:
            break
    
        # If we got fewer than 8 bits, pad with zeroes on the right
        if len(b) < 8:
            b = b + '0' * (8 - len(b))
    
        # Convert to int
        i = int(b, 2)
    
        # Convert to char
        c = chr(i)
    
        # Write
        f.write(c)
    
    f.close()

    …para que xxd -b outfile muestra…

    0000000: 00101101 01100000 10010000                             -`.
    De esta forma se rompe cuando los 8 bits fragmento comienza con «1», porque entonces la codificación utf-8 es más. Esto puede evitarse en Python 3, el uso de to_bytes.

    OriginalEl autor Aya

  3. 4

    Bien, después de un poco más de búsqueda, encontré una respuesta. Creo que el resto de ustedes simplemente no entender (que probablemente fue mi culpa, ya que tuve que editar dos veces para que quede claro). Me pareció aquí.

    La respuesta fue la división de cada pieza de datos, convertirlos en un entero binario, a continuación, ponerlos en una matriz binaria. Después de eso, usted puede utilizar la matriz de la tofile() método para escribir a un archivo.

    from array import *
    
    bin_array = array('B')
    
    bin_array.append(int('011',2))
    bin_array.append(int('010',2))
    bin_array.append(int('110',2))
    
    f = file('binary.mydata','wb')
    bin_array.tofile(f)
    f.close()

    OriginalEl autor KFox

  4. 1

    Breve ejemplo:

    my_number = 1234
    with open('myfile', 'wb') as file_handle:
        file_handle.write(struct.pack('i', my_number))
    ...
    with open('myfile', 'rb') as file_handle:
        my_number_back = struct.unpack('i', file_handle.read())[0]

    OriginalEl autor ThorSummoner

  5. 0

    Anexar a un array.array 3 bits en un momento todavía va a producir de 8 bits para cada valor. Anexar 011, 010, y 110 a una matriz y la escritura en el disco, se producirá el siguiente resultado: 00000011 00000010 00000110. Nota: todos los ceros acolchados allí.

    Parece que, en su lugar, desea «compacto» binario trillizos en bytes para ahorrar espacio. Dado el ejemplo de la cadena en su pregunta, usted puede convertir a una lista de enteros (8 bits) y, a continuación, escribir en un archivo directamente. Este paquete de todos los bits usando sólo 3 bits por valor, en lugar de 8.

    Python 3.4 ejemplo

    original_string = '001011010110000010010'
    
    # first split into 8-bit chunks
    bit_strings = [original_string[i:i + 8] for i in range(0, len(original_string), 8)]
    
    # then convert to integers
    byte_list = [int(b, 2) for b in bit_strings]
    
    with open('byte.dat', 'wb') as f:
        f.write(bytearray(byte_list))  # convert to bytearray before writing

    Contenido de byte.dat:

    • hex: 2D 60 12
    • binario (8 bits): 00101101 01100000 00010010
    • binario (3 bits): 001 011 010 110 000 000 010 010

                                          ^^ ^ (Note extra bits)

      Tenga en cuenta que este método de la almohadilla de los últimos valores de manera que se alinea con una de 8 bits límite, y el relleno va a los bits más significativos (lado izquierdo del último byte en el resultado anterior). Así que hay que tener cuidado, y posiblemente añadir ceros al final de su cadena original para hacer de su cadena de longitud múltiplo de 8.

    OriginalEl autor jdk1.0

Dejar respuesta

Please enter your comment!
Please enter your name here