[RESOLVIDO] Ler arquivo Binário

15 respostas
P

Eu pesquisei bastante mas não estou conseguindo nada.
Preciso ler um arquivo binário com 1325 bytes.
Os primeiros 1029 bytes acredito ser uma String só, depois 284 bytes são floats e tem mais uma string de 12 bytes.
Usei o DataInputStream e o readFloat() mas os valores que aparecem não correspondem ao arquivo.
Gostaria de um exemplo ou algo do tipo por favor.
O arquivo que estou tentando ler está anexado.

15 Respostas

E
0000	02 00 00 80 08 53 59 53  43 41 4C 20 50 72 6F 00   .....SYSCAL Pro.
0010	20 61 74 20 30 32 2F 30  33 2F 32 30 31 32 20 32    at 02/03/2012 2
0020	31 3A 33 31 3A 30 33 00  00 00 00 00 00 00 00 00   1:31:03.........
0030	00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
*
0400	00 00 00 00 00 04 00 02  00 00 00 FA 43 00 00 70   ............C..p
0410	42 01 00 00 00 00 00 00  00 00 00 0C 42 00 00 80   B...........B...
0420	41 00 00 98 41 00 00 00  00 00 00 00 00 00 00 00   A...A...........
0430	00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
0440	00 00 00 00 00 88 0A 88  42 D9 1E CD 3D 40 7C A0   ........B...=@|.
0450	3B C8 71 CB 45 00 00 00  00 61 ED BC 42 00 00 20   ;.q.E.....B.. 
0460	42 00 00 20 42 00 00 20  42 00 00 00 00 00 00 00   B.. B.. B.......
0470	00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
*
04F0	00 00 00 00 00 00 00 00  00 00 00 00 00 10 06 00   ................
0500	00 50 46 31 57 53 00 00  00 00 00 00 00 00 00 00   .PF1WS..........
0510	00 00 00 00 00 00 00 80  40 BF 3B 22 40 7F 88 C9   ........@.;"@...
0520	43 E6 1D 4B 41 6B E3 49  41 32 C8 20 42            C..KAkãIA2. B

Primeira coisa - como você sabe que há 284 bytes que são floats, e segunda coisa - como é que você sabe que os floats têm 4 bytes em vez de oito (ou talvez 6, se o arquivo foi gerado com uma versão antiga do Turbo Pascal) , e terceira coisa - sabendo que você tem floats, eles estão na ordem em que o C gravaria um float, ou na ordem em que o Java gravaria um float?

P

Pois é, eu não entendo nada.
O que eu disse foi pelo que eu acho.
Abri esse arquivo no hex editor e retornava o valor que eu esperava de 4 em 4 bytes por isso achei que eram floats.
Tem como me explicar melhor?
Como posso tentar ler esse arquivo?

E

Qual é o valor que você esperava?

P

Nesse arquivo existem vários valores, onde eu quero colocar em um JTable.
Os valores que procuro ler são a partir desse
1.83677e-040
depois vem outros
500
60
0
1.4013e-045
0.0
35.00
16.00
19.00

depois tem muitos 0.00
68.0
0.100
0.005
6510.22

e por ai vai tem mais outros valores

P

os valores que eu procuro a partir dessa linha:

0400    00 00 00 00 00 04 00 02  00 00 00 FA 43 00 00 70   ............C..p
E

Só para eu começar a entender como é que estão gravados os floats (não são doubles), eu escrevi o seguinte programa:

public class TestDouble {
static double[] dx = {
1.83677e-040,
500,
60,
0,
1.4013e-045,
0.0,
35.00,
16.00,
19.00,
68.0,
0.100,
0.005,
6510.22 ,
};
    public static void main (String[] args) {
		for (double d : dx) {
			System.out.printf ("%016X %08X %.6g %n", Double.doubleToLongBits (d), Float.floatToIntBits ((float) d), d);
		}
	}
}

Peguei a saída do programa, e vi que bate com alguns dos números que você informou. Só vou avisando que o Java entende os números de ponto flutuante em uma determinada sequencia e o C ou Assembly entende ao contrário, e é por isso que os números estão “ao contrário”.

Daí posso concluir que você não pode usar diretamente DataInputStream.readFloat porque ele supõe que os números estão em uma determinada ordem. Você tem de inverter os bytes, e aí você pode passar esses bytes para o método Float.intBitsToFloat. ( http://docs.oracle.com/javase/6/docs/api/java/lang/Float.html#intBitsToFloat(int) )

37B000224C3D727E 00020004 1.83677e-40
407F400000000000 43FA0000 500.000
404E000000000000 42700000 60.0000
0000000000000000 00000000 0.00000
36A00001262D4AB6 00000001 1.40130e-45
0000000000000000 00000000 0.00000
4041800000000000 420C0000 35.0000
4030000000000000 41800000 16.0000
4033000000000000 41980000 19.0000
4051000000000000 42880000 68.0000
3FB999999999999A 3DCCCCCD 0.100000
3F747AE147AE147B 3BA3D70A 0.00500000
40B96E3851EB851F 45CB71C3 6510.22

0000	02 00 00 80 08 53 59 53  43 41 4C 20 50 72 6F 00   .....SYSCAL Pro.
0010	20 61 74 20 30 32 2F 30  33 2F 32 30 31 32 20 32    at 02/03/2012 2
0020	31 3A 33 31 3A 30 33 00  00 00 00 00 00 00 00 00   1:31:03.........
0030	00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
*
0400	00 00 00 00 00 04 00 02  00 00 00 FA 43 00 00 70   ............C..p
                                    [500      ] [60     
0410	42 01 00 00 00 00 00 00  00 00 00 0C 42 00 00 80   B...........B...
         ] [1.401E-45] [0         ] [35.0     ] [16
0420	41 00 00 98 41 00 00 00  00 00 00 00 00 00 00 00   A...A...........
         ] [19       ] [0         ] [0        ] [0
0430	00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
         ] [0        ] [0         ] [0        ] [0
0440	00 00 00 00 00 88 0A 88  42 D9 1E CD 3D 40 7C A0   ........B...=@|.
         ] [0        ] [????      ] [0.1...   ] [0.005...
0450	3B C8 71 CB 45 00 00 00  00 61 ED BC 42 00 00 20   ;.q.E.....B.. 
         ] [6510.22  ] [0         ] [???      ] [????
0460	42 00 00 20 42 00 00 20  42 00 00 00 00 00 00 00   B.. B.. B.......
         ]
0470	00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
*
04F0	00 00 00 00 00 00 00 00  00 00 00 00 00 10 06 00   ................
0500	00 50 46 31 57 53 00 00  00 00 00 00 00 00 00 00   .PF1WS..........
0510	00 00 00 00 00 00 00 80  40 BF 3B 22 40 7F 88 C9   ........@.;"@...
0520	43 E6 1D 4B 41 6B E3 49  41 32 C8 20 42            C..KAkãIA2. B
E

Só mais uma coisinha. Pelo que imagino, esses valores esquisitos (1.83677e-040, 1.4013e-045) que um sistema de medição não iria gerar, não são doubles, e sim alguma tag ou outra coisa que serve para alguma função (sei lá qual é) dentro do arquivo. É que eles são na verdade conjuntos de bytes bem “bonitinhos” (mais parecidos com códigos ou tags do que números de ponto-flutuante.

P

Muito obrigado mesmo, vou tentar aqui.
Sobre o número 1.83677e-040 ele realmente não é um float, ele é um texto “Schlum. VES”.
1.4013e-045 esse eu não descobri o que é ainda.
No caso do Schlum. VES, como faço pra ler desse jeito?

E

Você vai ter de verificar se existe alguma documentação para esse formato. Para termos “00020004” e entender esse valor como “Schlum.VES” vai uma boa viagem :slight_smile:

P

Me desculpa pela pergunta, mas inverter os bytes?
Encontrei os bytes 0 46 2 12
Ai eu coloco 12 2 46 0?
ai uso o Float.intBitsToFloat
Assim?

P

Eu olhei no hex editor e no DWord corresponde ao valor necessário para eu utilizar o Float.intBitsToFloat

Float.intBitsToFloat[telefone removido]);
Vai dar o valor que eu espero!!
Como faço pra ler esse DWord que eu não entendi o que significa?

L
entanglement:
Só para eu começar a entender como é que estão gravados os floats (não são doubles), eu escrevi o seguinte programa:
public class TestDouble {
static double[] dx = {
1.83677e-040,
500,
60,
0,
1.4013e-045,
0.0,
35.00,
16.00,
19.00,
68.0,
0.100,
0.005,
6510.22 ,
};
    public static void main (String[] args) {
		for (double d : dx) {
			System.out.printf ("%016X %08X %.6g %n", Double.doubleToLongBits (d), Float.floatToIntBits ((float) d), d);
		}
	}
}

Peguei a saída do programa, e vi que bate com alguns dos números que você informou. Só vou avisando que o Java entende os números de ponto flutuante em uma determinada sequencia e o C ou Assembly entende ao contrário, e é por isso que os números estão "ao contrário".

Daí posso concluir que você não pode usar diretamente DataInputStream.readFloat porque ele supõe que os números estão em uma determinada ordem. Você tem de inverter os bytes, e aí você pode passar esses bytes para o método Float.intBitsToFloat. ( http://docs.oracle.com/javase/6/docs/api/java/lang/Float.html#intBitsToFloat%28int%29 )

37B000224C3D727E 00020004 1.83677e-40
407F400000000000 43FA0000 500.000
404E000000000000 42700000 60.0000
0000000000000000 00000000 0.00000
36A00001262D4AB6 00000001 1.40130e-45
0000000000000000 00000000 0.00000
4041800000000000 420C0000 35.0000
4030000000000000 41800000 16.0000
4033000000000000 41980000 19.0000
4051000000000000 42880000 68.0000
3FB999999999999A 3DCCCCCD 0.100000
3F747AE147AE147B 3BA3D70A 0.00500000
40B96E3851EB851F 45CB71C3 6510.22

0000	02 00 00 80 08 53 59 53  43 41 4C 20 50 72 6F 00   .....SYSCAL Pro.
0010	20 61 74 20 30 32 2F 30  33 2F 32 30 31 32 20 32    at 02/03/2012 2
0020	31 3A 33 31 3A 30 33 00  00 00 00 00 00 00 00 00   1:31:03.........
0030	00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
*
0400	00 00 00 00 00 04 00 02  00 00 00 FA 43 00 00 70   ............C..p
                                    [500      ] [60     
0410	42 01 00 00 00 00 00 00  00 00 00 0C 42 00 00 80   B...........B...
         ] [1.401E-45] [0         ] [35.0     ] [16
0420	41 00 00 98 41 00 00 00  00 00 00 00 00 00 00 00   A...A...........
         ] [19       ] [0         ] [0        ] [0
0430	00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
         ] [0        ] [0         ] [0        ] [0
0440	00 00 00 00 00 88 0A 88  42 D9 1E CD 3D 40 7C A0   ........B...=@|.
         ] [0        ] [????      ] [0.1...   ] [0.005...
0450	3B C8 71 CB 45 00 00 00  00 61 ED BC 42 00 00 20   ;.q.E.....B.. 
         ] [6510.22  ] [0         ] [???      ] [????
0460	42 00 00 20 42 00 00 20  42 00 00 00 00 00 00 00   B.. B.. B.......
         ]
0470	00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
*
04F0	00 00 00 00 00 00 00 00  00 00 00 00 00 10 06 00   ................
0500	00 50 46 31 57 53 00 00  00 00 00 00 00 00 00 00   .PF1WS..........
0510	00 00 00 00 00 00 00 80  40 BF 3B 22 40 7F 88 C9   ........@.;"@...
0520	43 E6 1D 4B 41 6B E3 49  41 32 C8 20 42            C..KAkãIA2. B

WTF :shock: ....Um dia eu chego nesse nível de conhecimento... :roll: Desculpe por não ajudar, mas tive que digitar isso.

P
while((po.read()) != -1){

		    	if(h>1027){
		    		 _flt = po.readInt();

		    		
		    	  _flt = ( (_flt >>> 24 & 0x000000FF)   
			               | (_flt >>>  8 & 0x0000FF00)   
			               | (_flt <<   8 & 0x00FF0000)   
			               | (_flt <<  24 & 0xFF000000));  
		    	  float flt = Float.intBitsToFloat(_flt);

		    	  System.out.println(flt);
		    	 

		    	}
		    		
		    	h++;
			 
		    	}

Achei esse código do thingol aqui no forum e ele tá me dando os valores certos, masss...
o readInt() tá lendo de 5 em 5 bytes!! porque???? :cry::(

P

Já imagino o que poder ser…
Só não sei como corrigir ainda.

P

Já consegui…
entanglement muito obrigado mesmo!

Criado 20 de junho de 2012
Ultima resposta 22 de jun. de 2012
Respostas 15
Participantes 3