2009-10-19 5 views
0

MyWriter.java (exécuter cette avant MyReader.java)lors de l'écriture d'octets d'écriture OutputStream (en interne), alors pourquoi la lecture de InputStream renvoie int?

import java.io.*; 
import java.net.*; 
import java.util.* ; 

public class MyWriter { 

    public static void main(String[] args) throws Exception { 

     ServerSocket ss = new ServerSocket(1234) ; 
     System.out.println("Server started...\n\n") ; 
     Socket s = ss.accept() ; 

     OutputStream out = s.getOutputStream() ; 

     Scanner scan = new Scanner(System.in) ; 

     while(true){ 
      System.out.print("Enter integer (or something else to quit) : "); 

      try{ 
       int i = scan.nextInt() ; 
       out.write(i) ; 
      }catch(RuntimeException rte){ 
       System.out.println("\n\n") ; 
       rte.printStackTrace() ; 
       System.out.println("\n\n") ; 
       break ; 
      } 
     } 
    } 
} 

MyReader.java (seulement exécuté, lorsque vous avez terminé avec MyWriter.java)

import java.io.*; 
import java.net.*; 
import java.util.* ; 

public class MyReader { 

    public static void main(String[] args) throws Exception { 

     Socket s = new Socket("localhost", 1234) ; 

     InputStream is = s.getInputStream() ; 

     int i ; 
     while((i = is.read()) != -1){ 
      System.out.println("character form : " + (char)i + ", int form : " + i); 
     } 
    } 
} 

Problème: MyReader ne se termine pas, même si je passe -1 dans MyWriter.

+0

Est-ce MyWriter fin? Il devrait imprimer une trace de pile et le processus devrait quitter. Si ce n'est pas le cas, le socket est toujours ouvert et le lecteur bloquera l'attente de plus de saisie. – erickson

+0

il ne se termine que pour une valeur non-entière (les exceptions ne sont pas gérées correctement pour que le code pointe sur le problème exact). sinon, il est dans while (true) loop. Considérons que mon entrée est seulement un entier avec l'une des entrées possibles -1, pour lesquelles MyReader se termine, mais elle ne se termine pas. – mogli

Répondre

3

Lecture renvoie un int de sorte qu'il peut également indiquer la fin du flux, comme -1. Si la signature était

byte read() 

alors vous ne saurez jamais quand le flux a été terminé (à moins qu'il ait jeté une exception, je suppose).

Je soupçonne qu'il n'y a aucune raison particulière pour write de prendre un int - il me semble un choix un peu étrange pour moi. Le Javadoc dit spécifiquement que les 24 bits supérieurs sont ignorés. Peut-être que c'est juste un accident de l'histoire.

(Dans .NET, Stream.ReadByte retourne un int, mais Stream.WriteByte prend un byte. Cela a plus de sens de l'OMI.)

Maintenant, avec ce fond, lorsque vous écrivez "-1" à votre flux, vous re écrit réellement la valeur "255" - et c'est ce que vous lisez. "-1" est représenté en binaire par "tous les 1", de sorte que les 8 bits inférieurs de ce sont "11111111" qui est 255 lorsqu'il est considéré comme une valeur non signée.

Votre lecteur se termine uniquement lorsque vous fermez le flux de sortie dans l'application "écriture" - car lorsque read() renverra -1.

+0

alors pourquoi ici MyReader ne se termine pas pour -1 entrée. – mogli

+0

J'étais en train d'éditer pour expliquer cela. –

+0

thnx M. Skeet :) – mogli

0

La meilleure façon de déterminer ce qui ne va pas avec le code est de le déboguer, en plus de regarder le doc java.

Dans ce cas, la méthode de lecture ne retournera -1 qu'à la fin du flux, sinon les valeurs renvoyées par la méthode sont comprises entre 0 et 255.

C'est le Java Doc de la méthode:

/** 
* Reads the next byte of data from the input stream. The value byte is 
* returned as an <code>int</code> in the range <code>0</code> to 
* <code>255</code>. If no byte is available because the end of the stream 
* has been reached, the value <code>-1</code> is returned. This method 
* blocks until input data is available, the end of the stream is detected, 
* or an exception is thrown. 
* 
* <p> A subclass must provide an implementation of this method. 
* 
* @return  the next byte of data, or <code>-1</code> if the end of the 
*    stream is reached. 
* @exception IOException if an I/O error occurs. 
*/ 

J'ai réécrit la classe afin de faciliter le débogage:

java.io.InputStream d'importation; import java.net.Socket;

MyReader public class {

public static void main(String[] args) throws Exception { 
    Socket s = new Socket("localhost", 1234); 
    InputStream is = s.getInputStream(); 

    int i; 
    do { 
     i = is.read(); 
     System.out.println("character form : " + (char) i + ", int form : " + i); 
    } while (i != -1); 
} 

}

have fun;)

Questions connexes