J'ai un bitset et je veux l'écrire dans un fichier - je suis tombé sur une solution pour utiliser une optionOutputStream à l'aide de la méthode WriteObject.
J'ai regardé l'objetOutPutStream dans l'API Java et j'ai vu que vous pouvez écrire d'autres choses (octet, int, court etc.) p>
J'ai essayé de vérifier la classe afin que j'ai essayé d'écrire un octet à un fichier à l'aide du code suivant, mais le résultat me donne un fichier avec 7 octets au lieu de 1 octet P>
Ma question est quels sont les 6 premiers octets du fichier? Pourquoi sont-ils là-bas? p>
Ma question est pertinente pour un bitset car je ne veux pas commencer à écrire beaucoup de données dans un fichier et réalisez que j'ai des octets aléatoires insérés dans le fichier sans savoir ce qu'ils sont. p>
Voici le code: p> merci pour toute aide p> AVNER P> P>
4 Réponses :
Vous pouvez écrire des objets sur un Si vous savez que le flux contiendra toujours un bitset, n'utilisez pas un ObjectOutPutStream code>, de sorte que le flux contient des informations sur les types écrits ainsi que les données nécessaires pour reconstituer l'objet. P>
ObjectOutPutStream code> - et si l'espace est une prime, puis convertissez le
bitset code> à un ensemble d'octets où chaque bit correspond à un peu dans le
bitset code>, puis écrivez-en directement sur le flux sous-jacent (par exemple, un
FileOutOutStream code> comme dans votre exemple). P>
Malheureusement, Bitset n'a pas de méthode intégrée pour la convertir en une gamme d'octets.
Il y a la méthode: TobyeArray () code>
@ clankill3r: Oui, avec Tolongarray () code>, mais seulement depuis Java 7.
Les autres octets seront des informations de type. P>
Fondamentalement ObjectOutPutStream est une classe utilisée pour écrire des objets sérialisables à une destination (généralement un fichier). Cela a plus de sens si vous pensez à InputObjectstream. Il a une méthode LisaObject () dessus. Comment Java sait-elle quel objet instancier? Facile: il y a des informations de type là-bas. P>
Donc, si je vous comprends correctement - chaque fois que j'écris quelque chose en utilisant ObjectOutputStream, je reçois des frais généraux sérieux pour chaque écriture. Par exemple, si j'écris un int, un court, un octet et une chaîne, je reçois 4 séries de données supplémentaires pour chaque article que j'écris?
Non. Seule la méthode WriteObject () ajoute l'en-tête de type. La méthode ERITUTF () ajoute un préfixe de lenght de 2 octets. Les méthodes primitive extritexx () n'ajoutent aucun aérien. Lisez l'API DOC pour plus de détails.
Notez également que les informations de type sont par objet. Pour un objet qui consiste essentiellement d'une matrice primitive (telle que Bitset), la surcharge est constante, quelle que soit la taille de la matrice.
Le format de sérialisation, comme beaucoup d'autres, comprend un en-tête avec des informations de numéro magique et de version. Lorsque vous utilisez dataOutputtput code> /
sortiestream code> méthodes sur
ObjectOutPutStream code> sont placés au milieu des données sérialisées ( sans aucun type d'information forte >). Ceci est typiquement uniquement dans
WriteObject CODE> implémentations après un appel sur
defaultwriteObject code> ou d'utilisation de
Putfields code>. p>
Si vous utilisez uniquement le bitset enregistré en Java, la sérialisation fonctionne bien. Cependant, c'est un peu ennuyeux si vous voulez partager le bitset sur plusieurs plates-formes multiples. Outre les frais généraux de la sérialisation Java, le bitset est stocké en unités de 8 octets. Cela peut générer trop de frais généraux si votre bitset est petit.
Nous avons écrit cette petite classe afin que nous puissions exagérer des tableaux d'octets de Bitset. En fonction de votre usecase, cela pourrait fonctionner mieux que la sérialisation Java pour vous. P>
public class ExportableBitSet extends BitSet { private static final long serialVersionUID = 1L; public ExportableBitSet() { super(); } public ExportableBitSet(int nbits) { super(nbits); } public ExportableBitSet(byte[] bytes) { this(bytes == null? 0 : bytes.length*8); for (int i = 0; i < size(); i++) { if (isBitOn(i, bytes)) set(i); } } public byte[] toByteArray() { if (size() == 0) return new byte[0]; // Find highest bit int hiBit = -1; for (int i = 0; i < size(); i++) { if (get(i)) hiBit = i; } int n = (hiBit + 8) / 8; byte[] bytes = new byte[n]; if (n == 0) return bytes; Arrays.fill(bytes, (byte)0); for (int i=0; i<n*8; i++) { if (get(i)) setBit(i, bytes); } return bytes; } protected static int BIT_MASK[] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01}; protected static boolean isBitOn(int bit, byte[] bytes) { int size = bytes == null ? 0 : bytes.length*8; if (bit >= size) return false; return (bytes[bit/8] & BIT_MASK[bit%8]) != 0; } protected static void setBit(int bit, byte[] bytes) { int size = bytes == null ? 0 : bytes.length*8; if (bit >= size) throw new ArrayIndexOutOfBoundsException("Byte array too small"); bytes[bit/8] |= BIT_MASK[bit%8]; } }