2010-11-15 5 views
0

J'utilisais StringReader dans une affectation Structures de données (codes Huffman), et je testais si la fin de la chaîne avait été atteinte. J'ai trouvé que la valeur int que StringReader.read() renvoie n'est pas -1, mais 65535, donc la conversion du résultat en un octet a résolu mon problème de boucle infinie que j'avais.Pourquoi StringReader.Read() ne renvoie pas un octet?

Est-ce un bogue dans JDK, ou est-ce une pratique courante de transtyper les valeurs renvoyées par les appels Reader.read() en bytes? Ou est-ce que je manque quelque chose?

L'essentiel de mon code était quelque chose comme ceci:

StringReader sr = new StringReader("This is a test string"); 
char c; 
do { 
    c = sr.read(); 
//} while (c != -1);  //<--Broken 
} while ((byte)c != -1); //<--Works 

Répondre

4

En fait, cela ne compile même pas. Je reçois:

incompatibilité Type: ne peut pas convertir int carboniser

Depuis l'appel sr.read() retourne un int je vous suggère de le stocker en tant que tel.

Cette compile (et fonctionne comme prévu):

StringReader sr = new StringReader("This is a test string"); 
int i;    // <-- changed from char 
do { 
    i = sr.read(); 

    // ... and if you need a char... 
    char c = (char) i; 

} while (i != -1); // <-- works :-) 

Pourquoi ne pas StringReader.Read() retourne un octet?

Les chaînes sont composées de caractères Unicode de 16 bits. Ceux-ci ne rentreront pas dans un octet de 8 bits. On pourrait soutenir qu'un char aurait été suffisant, mais il n'y a pas de place pour fournir une indication que l'EOF est atteint.

+0

'char c = (char) -1; System.out.println (c! = - 1); 'compile pour moi –

+0

Si vous avez une variable' char c' (comme le fait l'OP), alors 'c = sr.read();' (comme l'OP aussi a) ne compilera pas. – aioobe

+0

Le problème de largeur de chaîne a du sens, j'ai dû changer le cas de base de ma méthode récursive, et je viens de tester sans lancer à (octet) et tout va bien à nouveau> _ <. Voici maintenant une opportunité d'en apprendre plus. . . –

1

StringReader#read retourne une valeur int qui est -1 si la fin du flux a été atteint.

Le problème dans votre code est que vous avez déjà convertir la valeur int en char et tester le charbon:

System.out.println("Is it still (-1)?: " + (int) ((char) -1)); 
1

caractères en Java sont 2 octets parce qu'ils sont codés en UTF-16. C'est pourquoi read() renvoie un int, car l'octet n'est pas assez grand.

1
char c = (char) -1; 
     System.out.println(""+c); 
     System.out.println(""+(byte)c); 

Ce code permettra de résoudre votre doute ..

1

A Java String est une séquence de chars qui ne sont pas octets, mais les valeurs qui représentent le code points UTF-16. La sémantique de read consiste à renvoyer le prochain atome du flux d'entrée. Dans le cas d'un StringReader, le composant atomique est une valeur de 16 bits qui ne peut pas être représentée sous la forme d'un seul octet.

Questions connexes