75 votes

Convertir 4 octets en int

Je suis en train de lire un fichier binaire comme ceci:

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.

Je sens que je dois saisir 4 octets à la fois, et d'effectuer un "octet" ( comme >> << >> & FF et des trucs comme ça ) pour créer le nouveau type int

Quel est l'idiome pour cela?

MODIFIER

Ooops ce à son tour d'être un peu plus complexe ( à expliquer )

Ce que j'essaie de faire est de lire un fichier ( peut être au format ascii, binaire, il n'a pas d'importance ) et d'en extraire les entiers.

Par exemple, supposons que le contenu binaire ( en base 2 ) :

00000000 00000000 00000000 00000001
00000000 00000000 00000000 00000010

La représentation entière devrait être 1 , 2 droit? :- / 1 pour la première 32 bits, et 2 pour le reste de la 32 bits.

11111111 11111111 11111111 11111111

Serait -1

et

01111111 11111111 11111111 11111111

Serait Integer.MAX_VALUE ( 2147483647 )

74voto

Tom Points 5531

ByteBuffer a cette capacité et est capable de travailler avec des entiers petit et grand endian.

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());
 

J'espère que cela t'aides.

37voto

iTEgg Points 1753

Si vous les avez déjà dans un tableau d'octets [], vous pouvez utiliser:

 int result = ByteBuffer.wrap(bytes).getInt();
 

source: ici

28voto

cletus Points 276888

Vous devriez le mettre dans une fonction comme ceci:

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

Cela prend soin de manquer d'octets et de gérer correctement négatif valeurs d'octets.

Je suis pas au courant d'une fonction de base pour ce faire.

Questions à considérer:

  1. Endianness: les différentes architectures des processeurs mettre les octets qui composent un int dans des ordres différents. En fonction de comment vous est venu le tableau d'octets pour commencer, vous pourriez avoir à vous inquiéter à ce sujet; et

  2. Mise en mémoire tampon: si vous prenez 1024 octets à la fois et de commencer une séquence de l'élément 1022 vous atteignez la fin de la mémoire tampon avant de vous obtenez 4 octets. Il est probablement préférable d'utiliser une certaine forme de tampon du flux d'entrée qui ne le tampon automatiquement de sorte que vous pouvez simplement utiliser readByte() à plusieurs reprises et ne pas s'inquiéter autrement;

  3. Fuite de mémoire Tampon: la fin de l'entrée peut être un nombre impair d'octets (pas un multiple de 4), selon la source. Mais si vous créez l'entrée pour commencer et être un multiple de 4 est "garanti" (ou au moins une condition préalable) vous ne pouvez pas besoin de vous soucier de cela.

pour de plus amples précisions sur le point de mise en mémoire tampon, considérer l' BufferedInputStream:

InputStream in = new BufferedInputStream(new FileInputStream(file), 1024);

Maintenant, vous avez un InputStream qui automatiquement tampons de 1024 octets à la fois, ce qui est beaucoup moins difficile à traiter. De cette façon, vous pouvez heureusement lire 4 octets à la fois et ne pas s'inquiéter trop d'I/O.

D'autre part, vous pouvez également utiliser DataInputStream:

InputStream in = new DataInputStream(new BufferedInputStream(
                     new FileInputStream(file), 1024));
byte b = in.readByte();

ou encore:

int i = in.readInt();

et vous inquiétez pas à propos de la construction d' ints à tous.

17voto

Santhosh Kumar T Points 967

il suffit de voir comment DataInputStream.readInt () est implémenté;

     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));
 

5voto

Taylor Leese Points 18895

Le moyen le plus simple 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();
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X