2012-11-09 3 views
-1

Je souhaite enregistrer les données dans un fichier binaire à l'aide de Java. Par exemple j'ai le numéro 101 et dans mon programme le fichier de sortie a 4 octets. Comment puis-je enregistrer le numéro seulement dans trois bits (101) dans le fichier de sortie? Mon programme ressemble à ceci:Enregistrer dans le fichier binaire

public static void main(String args[]) throws FileNotFoundException, IOException { 
    int i = 101; 
    DataOutputStream os = new DataOutputStream(new FileOutputStream("file")); 
    os.writeInt(i); 
    os.close(); 
} 

J'ai trouvé quelque chose comme ça: http://www.developer.nokia.com/Community/Wiki/Bit_Input/Output_Stream_utility_classes_for_efficient_data_transfer

+0

Cela n'a aucun sens. 2^6 <101 <2^7 donc il devrait prendre au moins 7 bits. Si vous voulez traiter les chiffres 101 comme des caractères, utilisez un tableau char. Et préparez votre programme à se bloquer chaque fois qu'il reçoit un nombre qui n'est pas composé de 0 et 1, par ex. 2, 13, 102, etc. – djechlin

+0

Le nombre '101' est un ensemble de bits. Je voudrais créer un fichier qui stocke la chaîne binaire et avoir moins de taille (j'utilise l'encodage Huffman), puis le fichier original avec du texte (UTF-8). – user1518451

+0

Ce n'est pas un ensemble de bits. C'est un nombre entier. La représentation binaire de cet entier est '1100101'. Le seul bitset il serait logique de l'interpréter comme est '1100101'. Utilisez le type de données correct. – djechlin

Répondre

2

Vous ne pouvez pas écrire moins d'un octet dans un fichier. Si vous voulez écrire le nombre binaire 101, faites int i = 5 et utilisez os.write(i) à la place. Cela écrira un octet: 0000 0101.

+0

Vous ne savez pas ce que je veux dire. Je n'ai pas sauvegarder le nombre entier dans le fichier mais seulement l'ensemble des bits (seulement 1 ou 0).Par exemple la lettre 'a' a une représentation binaire 01000001 (UTF-8) mais quand j'utilise mon arbre Huffman 'a' j'ai une représentation binaire seulement 1011 et je dois enregistrer 'a' dans le fichier de sortie seulement sur 4 bits (pas 8) . – user1518451

+1

Si vous voulez stocker 2 choses dans un octet, vous devez composer manuellement l'octet à partir des parties, puis écrivez-le: 'os.write ((val1 & 0x0F) << 4 | (val2 & 0x0f))' –

+0

Et le question est de savoir comment puis-je stocker l'octet? Bien sûr, dans l'algorithme de Huffman, les lettres peuvent avoir différentes tailles. – user1518451

0

Tout d'abord, vous ne pouvez pas écrire seulement 3 bits dans un fichier, la mémoire est alignée sur des valeurs spécifiques (8, 16, 32, 64 ou même 128 bits, c'est un compilateur/plateforme spécifique). Si vous écrivez des tailles plus petites, elles seront agrandies pour correspondre à l'alignement.

Deuxièmement, le nombre décimal 101, écrit en binaire est 0b01100101. le nombre binaire 0b00000101, est décimal 5.

Troisièmement, ces nombres sont maintenant seulement 1 octet (8 bits) de long, de sorte que vous pouvez utiliser un caractère au lieu d'un int.

Et last but not least, d'écrire les nombres non entiers, utilisez os.write()

Donc, pour obtenir ce que vous voulez, vérifiez d'abord si vous voulez écrire 0b01100101 ou 0b00000101. Changez l'int en un caractère et au nombre approprié (vous pouvez écrire 0b01100101 en Java). Et utiliser os.write()

0

Une implémentation vraiment naïve, j'espère que cela vous aidera à saisir l'idée. Aussi non testé, susceptible de contenir hors par une erreur etc ...

class BitArray { 
    // public fields for example code, in real code encapsulate 
    public int bits=0; // actual count of stored bits 
    public byte[] buf=new byte[1]; 

    private void doubleBuf() { 
    byte [] tmp = new byte[buf.length * 2]; 
    System.arraycopy(buf, 0, tmp, 0, buf.length); 
    buf = tmp; 
    } 

    private int arrayIndex(int bitNum) { 
    return bitNum/8; 
    } 

    private int bitNumInArray(int bitNum) { 
    return bitNum & 7; // change to change bit order in buf's bytes 
    } 

    // returns how many elements of buf are actually in use, for saving etc. 
    // note that last element usually contains unused bits. 
    public int getUsedArrayElements() { 
    return arrayIndex(this.bits-1) + 1; 
    } 

    // bitvalue is 0 for 0, non-0 for 1 
    public void setBit(byte bitValue, int bitNum) { 
    if (bitNum >= this.bits || bitNum < 0) throw new InvalidArgumentException(); 
    if (bitValue == 0) this.buf[arrayIndex(bitNum)] &= ~((byte)1 << bitNumInArray(bitNum)); 
    else this.buf[arrayIndex(bitNum)] |= (byte)1 << bitNumInArray(bitNum); 
    } 

    public void addBit(int bitValue) { 
    // this.bits is old bit count, which is same as index of new last bit 
    if (this.buf.length <= arrayIndex(this.bits)) doubleBuf(); 
    ++this.bits; 
    setBit(bitValue, this.bits-1); 
    } 

    int readBit(int bitNum) { // return 0 or 1 
    if (bitNum >= this.bits || bitNum < 0) throw new InvalidArgumentException(); 
    byte value = buf[arrayIndex(bitNum)] & ((byte)1 << bitNumInArray(bitNum)); 
    return (value == 0) ? 0 : 1; 
    } 

    void addBits(int bitCount, int bitValues) { 
    for (int num = bitCount - 1 ; num >= 0 ; --num) { 
     // change loop iteration order to change bit order of bitValues 
     addBit(bitValues & (1 << num)); 
    } 
} 

Pour une solution efficace, il devrait utiliser int ou long tableau au lieu de tableau d'octets, et inclure la méthode plus efficace pour addition multiple bits (ajouter parties de bitValues un élément entier de tableau buf à la fois, pas bit par bit comme ci-dessus).

Pour sauvegarder ceci, vous devez sauvegarder le bon nombre d'octets de buf, calculé par getUsedArrayElements().

Questions connexes