Domanda

C# di BinaryReader ha una funzione che secondo MSDN, legge un numero intero codificato come "sette integer bit", e quindi legge una stringa con la lunghezza di questo numero intero.

C'è una chiara documentazione per il formato intero a sette bit (ho una conoscenza approssimativa che il MSB o LSB marchi se ci sono più byte da leggere, e i bit di riposo sono i dati, ma sarò felice per qualcosa di più esatto).

Ancora meglio, c'è un'implementazione C per i numeri di lettura e scrittura in questo formato?

È stato utile?

Soluzione

Bene, la documentazione per BinaryReader.Read7BitEncodedInt già dice che si aspetta il valore da scrivere con BinaryWriter.Write7BitEncodedInt e che la documentazione metodo illustra il formato:

  

Il numero intero del parametro valore viene scritto sette bit alla volta, a partire dai sette bit meno significativi. Il bit alto di un byte indica se ci sono più byte da scrivere dopo questo.

     

Se il valore si adatta a sette bit, richiede solo un byte di spazio. Se il valore non si adatta a sette bit, il bit alto si trova al primo byte e scritta. valore viene quindi spostata di sette bit e byte successivo è scritto. Questo processo viene ripetuto fino a quando l'intero intero è stato scritto.

Quindi, il numero intero 1259551277, in binario 1001011000100110011101000101101 sarà convertito in quel formato a 7 bit come segue:

Remaining integer                 encoded bytes
1001011000100110011101000101101
100101100010011001110100          00101101
10010110001001100                 10101101 01110100
1001011000                        10101101 11110100 01001100
100                               10101101 11110100 11001100 01011000
0                                 10101101 11110100 11001100 11011000 00000100

Non sono così fiducioso nelle mie capacità C in questo momento di fornire un'implementazione di lavoro, però. Ma non è molto difficile da fare, sulla base di tale descrizione.

Altri suggerimenti

In sostanza, l'idea alla base un Int32 codificato a 7 bit è di ridurre il numero di byte richiesto per piccoli valori. Funziona in questo modo:

  1. sono prese I primi 7 bit meno significativi del valore originale.
  2. Se questo valore supera quello che può adattarsi a queste 7 bit, il bit 8 è impostato a 1, indicando un altro byte deve essere letto. In caso contrario, che la bit è 0 e la lettura finisce qui.
  3. Il byte successivo viene letto, il suo valore spostato a sinistra di 7 bit e ORed al valore letto in precedenza per combinare insieme. Anche in questo caso, l'8 bit di questo byte indica se un altro byte deve essere letta (spostando il valore letto ulteriori 7 più volte).
  4. Questo continua fino a quando è stato letto un massimo di 5 byte (perché anche Int32.MaxValue non richiederebbe più di 5 byte quando soltanto 1 bit viene rubata ogni byte). Se il bit più alto del 5 ° byte è ancora impostato, avete letto qualcosa che non è un 7-bit codificato Int32.

Si noti che, dal momento che è scritto di byte per byte, endianness non importa a tutti per questi valori. è richiesto il seguente numero di byte per un determinato intervallo di valori:

  • 1 byte: da 0 a 127
  • 2 byte: 128 a 16.383
  • 3 byte: 16.384 a 2.097.151
  • 4 byte: 2.097.152 a 268.435.455
  • 5 byte: 268.435.456 su 2.147.483.647 (Int32.MaxValue) e --2,147,483,648 (Int32.MinValue) per -1

Come si può vedere, l'attuazione è un pò stupido e richiede sempre 5 byte per i valori negativi, come il bit del segno è il bit 32 ° del valore originale, sempre finire nel 5 ° byte.

Quindi, io non lo consiglio per i valori negativi o valori più grandi di ~ 250.000.000. Ho visto solo ha usato internamente per il prefisso di lunghezza della stringa di stringhe .NET (quelli che si possono leggere / scrivere con BinaryReader.ReadString e BinaryReader.WriteString), che descrive il numero di caratteri seguito della quale la corda si compone, avendo solo valori positivi.

Mentre è possibile cercare il href="https://referencesource.microsoft.com/#mscorlib/system/io/binaryreader.cs,f30b8b6e8ca06e0f,references" rel="nofollow noreferrer"> fonte NET originale , io uso diverse implementazioni nel mio BinaryData libreria .

ho dovuto esplorare questo formato 7-bit anche. In uno dei miei progetti imballo alcuni dati in file utilizzando BinaryWriter C # s 'e poi scompattarlo nuovo con BinaryReader, che funziona bene.

In seguito ho avuto bisogno di implementare un lettore per i file compressi di questo progetto per Java, anche. Java ha una classe denominata DataInputStream (nella confezione java.io), che ha alcuni metodi simili. Purtroppo l'interpretazione dei dati di DataInputStream è molto diverso da C # 's.

Per risolvere il mio problema ho portato BinaryReader C # s 'a Java me stesso, scrivendo una classe che estende java.io.DataInputStream. Ecco il metodo che ho scritto, che fa esattamente la stessa di C # 's BinaryReader.readString ():

public String csReadString() throws IOException {
    int stringLength = 0;
    boolean stringLengthParsed = false;
    int step = 0;
    while(!stringLengthParsed) {
        byte part = csReadByte();
        stringLengthParsed = (((int)part >> 7) == 0);
        int partCutter = part & 127;
        part = (byte)partCutter;
        int toAdd = (int)part << (step*7);
        stringLength += toAdd;
        step++;
    }
    char[] chars = new char[stringLength];
    for(int i = 0; i < stringLength; i++) {
        chars[i] = csReadChar();
    }
    return new String(chars);
}
/*
 * Parameters:  plOutput[out] - The decoded integer
 *              pbyInput[in]  - Buffer containing encoded integer
 * Returns:     Number of bytes used to encode the integer
 */
int SevenBitEncodingToInteger(int *plOutput, char *pbyInput)
{
    int lSize = 0;
    int lTemp = 0;
    while(true)
    {
        lTemp += pbyInput[lSize] & 0x7F;
        if(pbyInput[lSize++] > 127)
            lTemp <<= 7;
        else
            break;
    }
    *plOutput = lTemp;
    return lSize;
}

metodo Write7BitEncodedInt contiene la descrizione: La parte inferiore 7 bit di ciascun byte codificare i successivi 7 bit del numero. Il bit più alto è impostato quando c'è un altro seguito di byte.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top