Convertir 4 octets en int
je lis un fichier binaire comme celui-ci:
InputStream in = new FileInputStream( file );
byte[] buffer = new byte[1024];
while( ( in.read(buffer ) > -1 ) {
int a = // ???
}
Ce que je veux faire pour lire jusqu'à 4 octets et de créer une valeur int de ces mais, je ne sais pas comment le faire.
j'ai l'impression de devoir saisir 4 octets à la fois, et effectuer une opération "byte" (comme > > < > & FF et des trucs comme ça ) pour créer la nouvelle int
Quel est l'idiome de ceci?
EDIT
Ooops ce à son tour d'être un peu plus complexe ( à expliquer )
ce que j'essaie de faire, c'est de lire un fichier ( peut-être ascii, binaire, ça n'a pas d'importance ) et d'extraire les entiers qu'il peut avoir.
supposons par exemple le contenu binaire (en base 2 ) :
00000000 00000000 00000000 00000001
00000000 00000000 00000000 00000010
la représentation entière devrait être 1
, 2
n'est-ce pas? :- /1 pour les 32 premiers bits, et 2 pour les 32 restants bit.
11111111 11111111 11111111 11111111
serait -1
et
01111111 11111111 11111111 11111111
serait Integer.MAX_VALUE ( 2147483647 )
9 réponses
ByteBuffer a cette capacité, et est capable de travailler à la fois avec les petits et grands nombres entiers.
considérons cet exemple:
// read the file into a byte array
File file = new File("file.bin");
FileInputStream fis = new FileInputStream(file);
byte [] arr = new byte[(int)file.length()];
fis.read(arr);
// create a byte buffer and wrap the array
ByteBuffer bb = ByteBuffer.wrap(arr);
// if the file uses little endian as apposed to network
// (big endian, Java's native) format,
// then set the byte order of the ByteBuffer
if(use_little_endian)
bb.order(ByteOrder.LITTLE_ENDIAN);
// read your integers using ByteBuffer's getInt().
// four bytes converted into an integer!
System.out.println(bb.getInt());
Espérons que cette aide.
vous devriez le mettre dans une fonction comme celle-ci:
public static int toInt(byte[] bytes, int offset) {
int ret = 0;
for (int i=0; i<4 && i+offset<bytes.length; i++) {
ret <<= 8;
ret |= (int)bytes[i] & 0xFF;
}
return ret;
}
exemple:
byte[] bytes = new byte[]{-2, -4, -8, -16};
System.out.println(Integer.toBinaryString(toInt(bytes, 0)));
sortie:
11111110111111001111100011110000
Ce prend soin de manquer d'octets et de gérer correctement négatif valeurs d'octets.
Je ne connais pas de fonction standard pour faire ça.
Questions à prendre en considération:
-
Endianness: différentes architectures CPU mettent les octets qui composent un int dans des ordres différents. En fonction de la façon dont vous arrivez avec le tableau byte pour commencer avec vous mai à vous inquiéter à ce sujet; et
-
tampon: si vous saisissez 1024 octets à la fois et que vous démarrez une séquence à l'élément 1022, vous atteindrez la fin du tampon avant d'obtenir 4 octets. Il est probablement préférable d'utiliser une certaine forme de tampon du flux d'entrée Cela fait le tampon automatiquement de sorte que vous pouvez juste utiliser
readByte()
à plusieurs reprises et ne vous inquiétez pas à ce sujet autrement; -
tampon de fuite: la fin de l'entrée peut être un nombre impair d'octets (pas un multiple de 4 spécifiquement) selon la source. Mais si vous créez l'input pour commencer et être un multiple de 4 est "garanti" (ou au moins une condition préalable) vous pouvez ne pas avoir à vous en préoccuper.
InputStream in = new BufferedInputStream(new FileInputStream(file), 1024);
Maintenant vous avez un InputStream
que automatiquement tampons 1024 octets à la fois, ce qui est beaucoup moins difficile à traiter. De cette façon, vous pouvez lire avec plaisir 4 octets à la fois et ne pas vous inquiéter de trop I/O.
Deuxièmement, vous pouvez également utiliser DataInputStream
:
InputStream in = new DataInputStream(new BufferedInputStream(
new FileInputStream(file), 1024));
byte b = in.readByte();
ou même:
int i = in.readInt();
et ne vous inquiétez pas de construire int
s du tout.
voyez comment Dataainputstream.readInt ();
int ch1 = in.read();
int ch2 = in.read();
int ch3 = in.read();
int ch4 = in.read();
if ((ch1 | ch2 | ch3 | ch4) < 0)
throw new EOFException();
return ((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + (ch4 << 0));
la façon la plus facile est:
RandomAccessFile in = new RandomAccessFile("filename", "r");
int i = in.readInt();
-- ou --
DataInputStream in = new DataInputStream(new BufferedInputStream(
new FileInputStream("filename")));
int i = in.readInt();
essayez quelque chose comme ceci:
a = buffer[3];
a = a*256 + buffer[2];
a = a*256 + buffer[1];
a = a*256 + buffer[0];
ceci suppose que le plus petit octet vient en premier. si le octet le plus élevé vient en premier, vous pourriez avoir à échanger les indices (passer de 0 à 3).
fondamentalement pour chaque octet que vous voulez ajouter, vous multipliez d'abord a par 256 (qui égale un décalage vers la gauche par 8 bits) et ensuite ajouter le nouveau octet.
for (int i = 0; i < buffer.length; i++)
{
a = (a << 8) | buffer[i];
if (i % 3 == 0)
{
//a is ready
a = 0;
}
}
vous pouvez également utiliser BigInteger pour les octets de longueur variable. Vous pouvez le convertir en Long, entier ou court, selon vos besoins.
new BigInteger(bytes).intValue();
ou pour dénoter la polarité:
new BigInteger(1, bytes).intValue();
pour lire 4 octets non signés comme entier, nous devrions utiliser une variable longue, parce que le bit de signe est considéré comme faisant partie du nombre non signé.
long result = (((bytes[0] << 8 & bytes[1]) << 8 & bytes[2]) << 8) & bytes[3];
result = result & 0xFFFFFFFF;
cette fonction est testée et bien travaillée