C++ e Java - Leitura e Escrita de Arquivos

Estou com um problema e acredito que seja diferenças entre o modo como C++ e Java lêem e escrevem no arquivo:

Estou lendo o arquivo em C++, montando uma ByteMessage e transmitindo a um servidor Java que grava esse arquivo localmente.

Leio da sequinte maneira:

      int length;
      char * buffer;
      ifstream is;
      char fullPath [1024] = "";                                                
      sprintf(fullPath,"%s/%s",path,fileName);
      is.open (fullPath, ios::binary);  
      if (!is.fail())
      {
         is.seekg (0, ios::end);
         length = is.tellg();
         is.seekg (0, ios::beg);                
         buffer = new char [length];                
         is.read (buffer,length);//lê todo o arquivo
         is.close();           
      }
      BytesMessage* message = session->createBytesMessage((const unsigned char *)buffer,length);//Será enviada por JMS

Aí então a mensagem é enviada. Em Java, após receber a mensagem, gero o arquivo no servidor da seguinte maneira:

BytesMessage bm =  (BytesMessage) ((Message)mensagem);//Recebe via JMS
String tmpFile = fileName;//vem por parametro
File file = new File(tmpFile);							
FileOutputStream fos = new FileOutputStream(file);							
BufferedOutputStream outBuf = new BufferedOutputStream(fos);							
int i;							
while((i=bm.readInt())!=-1){//aqui o programa dá erro. 
   outBuf.write(i);
}							
outBuf.close();							
fos.close();

o Erro que ocorre é :

16:09:48,673 ERROR [STDERR] Caused by: java.io.EOFException
16:09:48,674 ERROR [STDERR] 	at java.io.DataInputStream.readInt(DataInputStream.java:375)
16:09:48,674 ERROR [STDERR] 	at org.apache.activemq.command.ActiveMQBytesMessage.readInt(ActiveMQBytesMessage.java:330)

O problema é que na maioria das vezes em que tento enviar um arquivo ocorre um erro no while com a instrução bm.readInt() enquanto tento gravar o arquivo buffer recebido e o programa dá crash. Suponho que seja problemas de diferença de leitura em c++ e Java mas não tenho certeza. Alguém sabe ou suspeita de algo?

uma coisa a se observar, e que geralmente gera problemas em comunicação é o BigEndian e LittleEndian

se o SO que está rodando o programa que lê o arquivo (C++) for Little Endian (windows, linux, …) e vc não estiver tratando o dado antes de enviar (htons e nthos) certamente vc terá algum problema, pois o padrão do Java é BigEndian (a menos que vc especifique o contrário)

outra coisa é que o readInt do Java é para 32 bits

((i=bm.readInt())!=-1)

o retorno -1 seria pra indicar q não tinha mais dados?

não faz sentido.

e se o valor do int a ser retornado fosse exatamente -1?

Bem pessoal, o que fiz foi substituir

while ((i=bm.readInt())!=-1) 

Por

((i=bm.readByte())!=-1) 

Me parece que há diferenças quanto a tipos primitivos entre c++ e Java, porém o valor Byte é 8 bits em ambos e agora está funcionando. Obrigado a todos pela ajuda.

[quote=ununes]Bem pessoal, o que fiz foi substituir

while ((i=bm.readInt())!=-1) 

Por

((i=bm.readByte())!=-1) 

Me parece que há diferenças quanto a tipos primitivos entre c++ e Java, porém o valor Byte é 8 bits em ambos e agora está funcionando. Obrigado a todos pela ajuda.[/quote]

o problema não é a diferenca entre c++ e java.

é a diferença entre readInt e readByte.

readByte retorna -1 qdo não tem mais dados.
readInt lança exceção.

lembra q questionei?
pq se ele lê 4 bytes, não seria possível ele reservar o 0xFFFFFFFF pra indicar q não tinha dados.
pq se eu tivesse feito do outro lado:
writeInt(-1);

Tanto em C quanto em Java, não se deve ler ou escrever um byte de cada vez se isso for possível.

Eu trocaria seu código em Java por algo como:

BytesMessage bm = (BytesMessage) mensagem;
BufferedOutputStream outBuf = null;
byte[] buffer = new byte[8 * 1024]; // por exemplo. 
try {
    bos = new BufferedOutputStream (new FileOutputStream (new File (tmpFile)));
	int nBytesLidos;
	while ((nBytesLidos = bm.readBytes (buffer)) > 0) {
		outBuf.write (buffer, 0, nBytesLidos);
	}
} catch (IOException ex) {
    .....
} finally {
    // Note que fechar o BufferedOutputStream já fecha automaticamente o FileOutputStream
	// associado. 
    if (bos != null) try { outBuf.close(); } catch (IOException ex2) { }
}