t
t
t
t
t t   11) Le système d’E/S de Java
tttt
t
carrea) Préface carreb) Avant-propos carre1) Introduction sur les &laqo; objets » carre2) Tout est &laqo; objet » carre3) Contrôle du flux du programme carre4) Initialization & Cleanup carre5) Cacher l'implémentation carre6) Réutiliser les classes carre7) Polymorphisme carre8) Interfaces & classes internes carre9) Stockage des objets carre10) Error Handling with Exceptions 11) Le système d’E/S de Java carre12) Identification dynamique de type carre13) Création de fenêtres & d'Applets carre14) Les &laqo; Threads » multiples carre15) Informatique distribuée carreA) Passage et retour d'objets carreB) L'Interface Java Natif (JNI) carreC) Conseils pour une programation stylée en Java carreD) Resources
Texte original t Traducteur : Armel Fortun
t
t
///
Ce chapitre contient 10 pages
1 2 3 4 5 6 7 8 9 10
\\\
t t t
t t t
t
t t t
Circle and Square are straightforward extensions of Shape; the only difference is that Circle initializes color at the point of definition and Square initializes it in the constructor. We’ll leave the discussion of Line for later.
t Circle and Square sont des extensions directes de Shape ; la seule différence est que Circle initialise color au point de définition et que Square l'initialise dans le constructeur. Nous laisserons la discussion sur Line pour plus tard.
t t t
In main( ), one ArrayList is used to hold the Class objects and the other to hold the shapes. If you don’t provide a command line argument the shapeTypes ArrayList is created and the Class objects are added, and then the shapes ArrayList is created and Shape objects are added. Next, all the static color values are set to GREEN, and everything is serialized to the file CADState.out.
t Dans main(), une ArrayList est employée pour tenir les objets de Class et les autres pour tenir les formes. Si vous ne fournissez pas un argument en ligne de commande la shapeTypes ArrayList est créé et les objets Class sont ajoutés, et ensuite l'ArrayList de shapes est créé et les objets Shape sont ajoutés. Puis, toutes les valeurs static de couleur (color) sont établies à GREEN, et tout est sérialisé vers le fichier CADState.out.
t t t
If you provide a command line argument (presumably CADState.out), that file is opened and used to restore the state of the program. In both situations, the resulting ArrayList of Shapes is printed. The results from one run are:
t Si l'on fournit un argument en ligne de commande (vraisemblablement CADState.out), ce fichier est ouvert et utilisé pour restituer l'état du programme. Dans les deux situations, l'ArrayList de Shapes est affichée. Le résultat d'une exécution donne :
t t t
>java CADState [class Circle color[3] xPos[-51] yPos[-99] dim[38] , class Square color[3] xPos[2] yPos[61] dim[-46] , class Line color[3] xPos[51] yPos[73] dim[64] , class Circle color[3] xPos[-70] yPos[1] dim[16] , class Square color[3] xPos[3] yPos[94] dim[-36] , class Line color[3] xPos[-84] yPos[-21] dim[-35] , class Circle color[3] xPos[-75] yPos[-43] dim[22] , class Square color[3] xPos[81] yPos[30] dim[-45] , class Line color[3] xPos[-29] yPos[92] dim[17] , class Circle color[3] xPos[17] yPos[90] dim[-76] ] >java CADState CADState.out [class Circle color[1] xPos[-51] yPos[-99] dim[38] , class Square color[0] xPos[2] yPos[61] dim[-46] , class Line color[3] xPos[51] yPos[73] dim[64] , class Circle color[1] xPos[-70] yPos[1] dim[16] , class Square color[0] xPos[3] yPos[94] dim[-36] , class Line color[3] xPos[-84] yPos[-21] dim[-35] , class Circle color[1] xPos[-75] yPos[-43] dim[22] , class Square color[0] xPos[81] yPos[30] dim[-45] , class Line color[3] xPos[-29] yPos[92] dim[17] , class Circle color[1] xPos[17] yPos[90] dim[-76] ] t
>java CADState
[class Circle color[3] xPos[-51] yPos[-99] dim[38]
, class Square color[3] xPos[2] yPos[61] dim[-46]
, class Line color[3] xPos[51] yPos[73] dim[64]
, class Circle color[3] xPos[-70] yPos[1] dim[16]
, class Square color[3] xPos[3] yPos[94] dim[-36]
, class Line color[3] xPos[-84] yPos[-21] dim[-35]
, class Circle color[3] xPos[-75] yPos[-43] dim[22]
, class Square color[3] xPos[81] yPos[30] dim[-45]
, class Line color[3] xPos[-29] yPos[92] dim[17]
, class Circle color[3] xPos[17] yPos[90] dim[-76]
]

>java CADState CADState.out
[class Circle color[1] xPos[-51] yPos[-99] dim[38]
, class Square color[0] xPos[2] yPos[61] dim[-46]
, class Line color[3] xPos[51] yPos[73] dim[64]
, class Circle color[1] xPos[-70] yPos[1] dim[16]
, class Square color[0] xPos[3] yPos[94] dim[-36]
, class Line color[3] xPos[-84] yPos[-21] dim[-35]
, class Circle color[1] xPos[-75] yPos[-43] dim[22]
, class Square color[0] xPos[81] yPos[30] dim[-45]
, class Line color[3] xPos[-29] yPos[92] dim[17]
, class Circle color[1] xPos[17] yPos[90] dim[-76]
]
t t t
You can see that the values of xPos, yPos, and dim were all stored and recovered successfully, but there’s something wrong with the retrieval of the static information. It’s all “3” going in, but it doesn’t come out that way. Circles have a value of 1 (RED, which is the definition), and Squares have a value of 0 (remember, they are initialized in the constructor). It’s as if the statics didn’t get serialized at all! That’s right—even though class Class is Serializable, it doesn’t do what you expect. So if you want to serialize statics, you must do it yourself.
t Vous pouvez voir que les valeurs d'xPos, yPos, et dim sont toutes stockées et récupérées avec succès, mais qu'il y a quelque chose d'anormal dans la récupération d'informations static. Les « 3 » rentrent bien, mais ne sortent pas de la même manière. Les Circles ont une valeur de 1 (RED, ce qui est la définition), et les Squares ont une valeur de 0 (rappelez-vous, ils sont initialisés dans le constructeur). C'est comme si les statics n'étaient pas sérialisées du tout ! Ce qui est correct — malgré que la class Class est Serializable, cela n'agit pas comme on pouvait l'espérer. Donc si vous désirez sérialiser des statics, vous devrez le faire vous-même.
t t t
This is what the serializeStaticState( ) and deserializeStaticState( ) static methods in Line are for. You can see that they are explicitly called as part of the storage and retrieval process. (Note that the order of writing to the serialize file and reading back from it must be maintained.) Thus to make CADState.java run correctly you must:
t C'est à quoi les méthodes static serializeStaticState() et deserializeStaticState() dans Line servent. Vous pouvez voir qu'elles sont appelés explicitement comme une partie du processus de stockage et de récupération. (Notez que l'ordre d'écriture vers le fichier sérialisé et de sa relecture doit être conservé.) Ainsi pour que CADState.java s'exécute correctement vous devez :
t t t
  1. Add a serializeStaticState( ) and deserializeStaticState( ) to the shapes.
  2. Remove the ArrayList shapeTypes and all code related to it.
  3. Add calls to the new serialize and deserialize static methods in the shapes.
t
  1. Ajouter un serializeStaticState() et un deserializeStaticState() aux figures [shapes].
  2. Enlever ArrayList shapeTypes et tout le code s'y rattachant.
  3. Ajouter des appels aux nouvelles méthodes statiques de sérialisation et de sérialisation dans les figures [shapes].
t t t
Another issue you might have to think about is security, since serialization also saves private data. If you have a security issue, those fields should be marked as transient. But then you have to design a secure way to store that information so that when you do a restore you can reset those private variables.
t Un autre sujet auquel vous devez penser est la sécurité, vu que la sérialisation sauve aussi les données private. Si vous vous avez orientation de sécurité, ces champs doivent être marqués comme transient. Mais alors vous devez concevoir une manière sûre pour stocker cette information de sorte que quand vous faites une restauration vous pouvez remettre à l'état initial [reset] ces variables privates.
t t t

Tokenizing input

t

Tokenizer l'entrée

t t t
Tokenizing is the process of breaking a sequence of characters into a sequence of “tokens,” which are bits of text delimited by whatever you choose. For example, your tokens could be words, and then they would be delimited by white space and punctuation. There are two classes provided in the standard Java library that can be used for tokenization: StreamTokenizer and StringTokenizer.
t Tokenizing est le processus de casser une séquence de caractères en un séquence de « tokens, » qui sont des morceaux de texte délimités par quoi que vous vous choisissez. Par exemple, vos jetons [tokens] peuvent être des mots, et ensuite ils pourront être délimités par un blanc et de la ponctuation. Il y a deux classes fournies dans la librairie standard de Java qui peuvent être employées pour la tokenisation : StreamTokenizer and StringTokenizer.
t t t

StreamTokenizer

t

StreamTokenizer

t t t
Although StreamTokenizer is not derived from InputStream or OutputStream, it works only with InputStream objects, so it rightfully belongs in the I/O portion of the library.
t Bien que StreamTokenizer ne soit pas dérivé d'InputStream ou OutputStream, il ne fonctionne qu'avec les objets InputStreams, donc il appartient à juste titre à la partie d'E/S de la librairie.
t t t
Consider a program to count the occurrence of words in a text file:
t Considérons un programme qui compte les occurrences de mots dans un fichier texte :
t t t
//: c11:WordCount.java // Counts words from a file, outputs // results in sorted form. import java.io.*; import java.util.*; class Counter { private int i = 1; int read() { return i; } void increment() { i++; } } public class WordCount { private FileReader file; private StreamTokenizer st; // A TreeMap keeps keys in sorted order: private TreeMap counts = new TreeMap(); WordCount(String filename) throws FileNotFoundException { try { file = new FileReader(filename); st = new StreamTokenizer( new BufferedReader(file)); st.ordinaryChar('.'); st.ordinaryChar('-'); } catch(FileNotFoundException e) { System.err.println( "Could not open " + filename); throw e; } } void cleanup() { try { file.close(); } catch(IOException e) { System.err.println( "file.close() unsuccessful"); } } void countWords() { try { while(st.nextToken() != StreamTokenizer.TT_EOF) { String s; switch(st.ttype) { case StreamTokenizer.TT_EOL: s = new String("EOL"); break; case StreamTokenizer.TT_NUMBER: s = Double.toString(st.nval); break; case StreamTokenizer.TT_WORD: s = st.sval; // Already a String break; default: // single character in ttype s = String.valueOf((char)st.ttype); } if(counts.containsKey(s)) ((Counter)counts.get(s)).increment(); else counts.put(s, new Counter()); } } catch(IOException e) { System.err.println( "st.nextToken() unsuccessful"); } } Collection values() { return counts.values(); } Set keySet() { return counts.keySet(); } Counter getCounter(String s) { return (Counter)counts.get(s); } public static void main(String[] args) throws FileNotFoundException { WordCount wc = new WordCount(args[0]); wc.countWords(); Iterator keys = wc.keySet().iterator(); while(keys.hasNext()) { String key = (String)keys.next(); System.out.println(key + ": " + wc.getCounter(key).read()); } wc.cleanup(); } } ///:~ t
//: c11:WordCount.java
// Compte les mots dans un fichier, produit
// les résultats dans un formulaire classé.
import java.io.*;
import java.util.*;

class Counter {
  private int i = 1;
  int read() { return i; }
  void increment() { i++; }
}

public class WordCount {
  private FileReader file;
  private StreamTokenizer st;
  // Un TreeMap conserve les clés dans un ordre classé :
  private TreeMap counts = new TreeMap();
  WordCount(String filename)
    throws FileNotFoundException {
    try {
      file = new FileReader(filename);
      st = new StreamTokenizer(
        new BufferedReader(file));
      st.ordinaryChar('.');
      st.ordinaryChar('-');
    } catch(FileNotFoundException e) {
      System.err.println(
        "Could not open " + filename);
      throw e;
    }
  }
  void cleanup() {
    try {
      file.close();
    } catch(IOException e) {
      System.err.println(
        "file.close() unsuccessful");
    }
  }
  void countWords() {
    try {
      while(st.nextToken() !=        StreamTokenizer.TT_EOF) {
        String s;
        switch(st.ttype) {
          case StreamTokenizer.TT_EOL:
            s = new String("EOL");
            break;
          case StreamTokenizer.TT_NUMBER:
            s = Double.toString(st.nval);
            break;
          case StreamTokenizer.TT_WORD:
            s = st.sval; // Déjà un String
            break;
          default: // un seul caractère dans type
            s = String.valueOf((char)st.ttype);
        }
        if(counts.containsKey(s))
          ((Counter)counts.get(s)).increment();
        else
          counts.put(s, new Counter());
      }
    } catch(IOException e) {
      System.err.println(
        "st.nextToken() unsuccessful");
    }
  }
  Collection values() {
    return counts.values();
  }
  Set keySet() { return counts.keySet(); }
  Counter getCounter(String s) {
    return (Counter)counts.get(s);
  }
  public static void main(String[] args)
  throws FileNotFoundException {
    WordCount wc =      new WordCount(args[0]);
    wc.countWords();
    Iterator keys = wc.keySet().iterator();
    while(keys.hasNext()) {
      String key = (String)keys.next();
      System.out.println(key + ": "
               + wc.getCounter(key).read());
    }
    wc.cleanup();
  }
} ///:~
t t t
Presenting the words in sorted form is easy to do by storing the data in a TreeMap, which automatically organizes its keys in sorted order (see Chapter 9). When you get a set of keys using keySet( ), they will also be in sorted order.
t Présenter les mots sous une forme classée est facile à faire en stockant les données dans un TreeMap, qui organise automatiquement ces clés dans un ordre classé (voir le Chapitre 9). Quand vous avez un jeu de clés en utilisant keySet() , elles seront automatiquement rangées dans l'ordre.
t t t
To open the file, a FileReader is used, and to turn the file into words a StreamTokenizer is created from the FileReader wrapped in a BufferedReader. In StreamTokenizer, there is a default list of separators, and you can add more with a set of methods. Here, ordinaryChar( ) is used to say “This character has no significance that I’m interested in,” so the parser doesn’t include it as part of any of the words that it creates. For example, saying st.ordinaryChar('.') means that periods will not be included as parts of the words that are parsed. You can find more information in the JDK HTML documentation from java.sun.com.
t Pour ouvrir le fichier, un FileReader est utilisé, et pour changer le fichier en mots un StreamTokenizer est créé depuis le FileReader enveloppé dans un BufferedReader. Dans StreamTokenizer, il y a une liste par défaut de séparateurs, et vous pouvez en ajouter d'autres avec un jeu de méthodes. Ici, ordinaryChar() est utilisé pour dire « Ce caractère n'a aucune signification pour que je m'y intéresse, » donc l'analyseur ne les incluras pas comme des parties de tous les mots qu'il va créer. Par exemple, dire st.ordinaryChar('.') veut dire que les points ne seront pas inclus comme des parties des mots qui seront analysés. Vous pourrez trouver plus d'information dans la documentation HTML du JDK à <java.sun.com>.
t t t
In countWords( ), the tokens are pulled one at a time from the stream, and the ttype information is used to determine what to do with each token, since a token can be an end-of-line, a number, a string, or a single character.
t Dans countWords(), les tokens sont tirés un à un depuis le stream, et l'information ttype est utilisée pour déterminer ce qu'il faut faire avec chaque token, vu qu'un token peut être une fin de ligne, un nombre, une chaîne de caractère [string], ou un simple caractère.
t t t
Once a token is found, the TreeMap counts is queried to see if it already contains the token as a key. If it does, the corresponding Counter object is incremented to indicate that another instance of this word has been found. If not, a new Counter is created—since the Counter constructor initializes its value to one, this also acts to count the word.
t Une fois qu'un token est trouvé, le counts de TreeMap est appelé pour voir si il contient déjà le token sous la forme d'une clé. Si c'est le cas, l'objet Counter correspondant est incrémenté pour indiquer qu'une autre instance de ce mots a été trouvée. Si ce n'est pas le cas, un nouveau Counter est créé — vu que le constructeur de Counter initialise sa valeur à un, ceci agit aussi pour compter le mot.
t t t
WordCount is not a type of TreeMap, so it wasn’t inherited. It performs a specific type of functionality, so even though the keys( ) and values( ) methods must be reexposed, that still doesn’t mean that inheritance should be used since a number of TreeMap methods are inappropriate here. In addition, other methods like getCounter( ), which get the Counter for a particular String, and sortedKeys( ), which produces an Iterator, finish the change in the shape of WordCount’s interface.
t WordCount n'est pas un type de TreeMap, donc il n'est pas hérité. Il accompli un type de fonctionnalité spécifique, ainsi bien que les méthodes keys() et values() doivent être re-exposées, cela ne veut pas forcément dire que l'héritage doit être utilisé vu qu'un bon nombre de méthodes de TreeMap sont ici inappropriés. En plus, les autres méthodes comme getCounter(), qui prend le Counter pour un String particulier, et sortedKeys(), qui produit un Iterator, terminant le changement dans la forme d'interface de WordCount..
t t t
In main( ) you can see the use of a WordCount to open and count the words in a file—it just takes two lines of code. Then an Iterator to a sorted list of keys (words) is extracted, and this is used to pull out each key and associated Count. The call to cleanup( ) is necessary to ensure that the file is closed.
t Dans main() vous pouvez voir l'emploi d'un WordCount pour ouvrir et compter les mots dans un fichier — cela ne prend que deux lignes de code. Puis un Iterator est extrait vers une liste triée de clés (mots), et est employé pour retirer chaque clé et Count associés. L'appel à cleanup() est nécessaire pour s'assurer que le fichier est fermé.
t t t

StringTokenizer

t

StringTokenizer

t t t
Although it isn’t part of the I/O library, the StringTokenizer has sufficiently similar functionality to StreamTokenizer that it will be described here.
t Bien qu'il ne fasse pas partie de la bibliothèque d'E/S, le StringTokenizer possède des fonctions assez similaires a StreamTokenizer comme il sera décrit ici.
t t t
The StringTokenizer returns the tokens within a string one at a time. These tokens are consecutive characters delimited by tabs, spaces, and newlines. Thus, the tokens of the string “Where is my cat?” are “Where”, “is”, “my”, and “cat?” Like the StreamTokenizer, you can tell the StringTokenizer to break up the input in any way that you want, but with StringTokenizer you do this by passing a second argument to the constructor, which is a String of the delimiters you wish to use. In general, if you need more sophistication, use a StreamTokenizer.
t Le StringTokenizer renvoie les tokens dans une chaîne de caractère un par un. Ces tokens sont des caractères consécutifs délimités par des tabulations, des espaces, et des nouvelles lignes. Ainsi, les tokens de la chaîne de caractère « Où est mon chat ? » sont « Où, » « est, » « mon, » « chat, » « ?. » Comme le StreamTokenizer, vous pouvez appeler le StringTokenizer pour casser l'entrée de n'importe quelle manière, mais avec StringTokenizer vous effectuez cela en passant un second argument au constructeur, qui est un String des délimiteurs que vous utiliserez. En général, si vous désirez plus de sophistication, employez un StreamTokenizer.
t t t
You ask a StringTokenizer object for the next token in the string using the nextToken( ) method, which either returns the token or an empty string to indicate that no tokens remain.
t Vous appelez un objet StringTokenizer pour le prochain token dans la chaîne de caractère en utilisant la méthode nextToken(), qui renvoie soit un token ou une chaîne de caractère vide pour indiquer qu'il ne reste pas de tokens.
t t t
As an example, the following program performs a limited analysis of a sentence, looking for key phrase sequences to indicate whether happiness or sadness is implied.
t Comme exemple, le programme suivant exécute une analyse limitée d'une phrase, cherchant des phrases clés pour indiquer si la joie ou la tristesse sont sous-entendues.
t t t
//: c11:AnalyzeSentence.java // Look for particular sequences in sentences. import java.util.*; public class AnalyzeSentence { public static void main(String[] args) { analyze("I am happy about this"); analyze("I am not happy about this"); analyze("I am not! I am happy"); analyze("I am sad about this"); analyze("I am not sad about this"); analyze("I am not! I am sad"); analyze("Are you happy about this?"); analyze("Are you sad about this?"); analyze("It's you! I am happy"); analyze("It's you! I am sad"); } static StringTokenizer st; static void analyze(String s) { prt("\nnew sentence >> " + s); boolean sad = false; st = new StringTokenizer(s); while (st.hasMoreTokens()) { String token = next(); // Look until you find one of the // two starting tokens: if(!token.equals("I") && !token.equals("Are")) continue; // Top of while loop if(token.equals("I")) { String tk2 = next(); if(!tk2.equals("am")) // Must be after I break; // Out of while loop else { String tk3 = next(); if(tk3.equals("sad")) { sad = true; break; // Out of while loop } if (tk3.equals("not")) { String tk4 = next(); if(tk4.equals("sad")) break; // Leave sad false if(tk4.equals("happy")) { sad = true; break; } } } } if(token.equals("Are")) { String tk2 = next(); if(!tk2.equals("you")) break; // Must be after Are String tk3 = next(); if(tk3.equals("sad")) sad = true; break; // Out of while loop } } if(sad) prt("Sad detected"); } static String next() { if(st.hasMoreTokens()) { String s = st.nextToken(); prt(s); return s; } else return ""; } static void prt(String s) { System.out.println(s); } } ///:~ t
//: c11:AnalyzeSentence.java
// Cherche des séries particulières dans les phrases.
import java.util.*;

public class AnalyzeSentence {
  public static void main(String[] args) {
    analyze("I am happy about this");
    analyze("I am not happy about this");
    analyze("I am not! I am happy");
    analyze("I am sad about this");
    analyze("I am not sad about this");
    analyze("I am not! I am sad");
    analyze("Are you happy about this?");
    analyze("Are you sad about this?");
    analyze("It's you! I am happy");
    analyze("It's you! I am sad");
  }
  static StringTokenizer st;
  static void analyze(String s) {
    prt("\nnew sentence >> " + s);
    boolean sad = false;
    st = new StringTokenizer(s);
    while (st.hasMoreTokens()) {
      String token = next();
      // Cherche jusqu'à ce l'on trouve un des
      // deux tokens de départ :
      if(!token.equals("I") &&
         !token.equals("Are"))
        continue; // Haut de la boucle while
      if(token.equals("I")) {
        String tk2 = next();
        if(!tk2.equals("am")) // Doit être après I
          break; // Sortie de la boucle while
        else {
          String tk3 = next();
          if(tk3.equals("sad")) {
            sad = true;
            break; // Sortie de la boucle while
          }
          if (tk3.equals("not")) {
            String tk4 = next();
            if(tk4.equals("sad"))
              break; // Laisse sad faux
            if(tk4.equals("happy")) {
              sad = true;
              break;
            }
          }
        }
      }
      if(token.equals("Are")) {
        String tk2 = next();
        if(!tk2.equals("you"))
          break; // Doit être après Are
        String tk3 = next();
        if(tk3.equals("sad"))
          sad = true;
        break; // Sortie de la boucle while
      }
    }
    if(sad) prt("Sad detected");
  }
  static String next() {
    if(st.hasMoreTokens()) {
      String s = st.nextToken();
      prt(s);
      return s;
    }
    else
      return "";
  }
  static void prt(String s) {
    System.out.println(s);
  }
} ///:~
t t t
For each string being analyzed, a while loop is entered and tokens are pulled off the string. Notice the first if statement, which says to continue (go back to the beginning of the loop and start again) if the token is neither an “I” nor an “Are.” This means that it will get tokens until an “I” or an “Are” is found. You might think to use the == instead of the equals( ) method, but that won’t work correctly, since == compares reference values while equals( ) compares contents.
t Pour que chaque chaîne de caractère soit analysée, une boucle while est entrée et les tokens sont poussés hors de la chaîne de caractères. Notez la première déclaration de if, qui dit de continuer (retourne au début de la boucle et recommence encore) si le token est ni un « I » ou un « Are. » Ceci signifie qu'il attrapera les tokens que si un « I » ou un « Are » est trouvé. Vous pourriez penser utiliser le == à la place de la méthode equals(), mais cela ne fonctionne pas correctement, comme == compare les références de valeur tandis qu'equals() compare les contenus.
t t t
The logic of the rest of the analyze( ) method is that the pattern that’s being searched for is “I am sad,” “I am not happy,” or “Are you sad?” Without the break statement, the code for this would be even messier than it is. You should be aware that a typical parser (this is a primitive example of one) normally has a table of these tokens and a piece of code that moves through the states in the table as new tokens are read.
t La logique du reste de la méthode analyze() est que le pattern (motif) dont on recherche la présence est « I am sad, » « I am not happy, » or « Are you sad? » Sans la déclaration break, le code réalisant ça serait bien plus confus qu'il ne l'est. Vous devez être conscient qu'un parseur typique (ceci en est un exemple primitif) possède normalement une table de ces tokens et un morceau de code qui bouge de l'un à l'autre des statuts dans la table quand les nouveaux tokens sont lus.
t t t
You should think of the StringTokenizer only as shorthand for a simple and specific kind of StreamTokenizer. However, if you have a String that you want to tokenize and StringTokenizer is too limited, all you have to do is turn it into a stream with StringBufferInputStream and then use that to create a much more powerful StreamTokenizer.
t Vous pourrez voir le StringTokenizer seulement comme un raccourci pour un type de StreamTokenizer simple et spécifique. Cependant, si vous avez un String que vous désirez tokenizer et que StringTokenizer est trop limité, tout ce que vous avez à faire est de le retourner dans un flux avec StringBufferInputStream puis de l'utiliser pour créer un StreamTokenizer beaucoup plus puissant.
t t t

Checking capitalization style

t

Vérifier le style de capitalization

t t t
In this section we’ll look at a more complete example of the use of Java I/O, which also uses tokenization. This project is directly useful because it performs a style check to make sure that your capitalization conforms to the Java style as found at java.sun.com/docs/codeconv/index.html. It opens each .java file in the current directory and extracts all the class names and identifiers, then shows you if any of them don’t meet the Java style.
t Dans cette partie on observera un exemple un peut plus complet d'utilisation du Java E/S. Ce projet est directement utile puisqu'il accomplit une vérification de style pour être sur que la capitalisation se conforme au style Java comme décrit surjava.sun.com/docs/codeconv/index.html. Il ouvre chaque fichier .java dans le répertoire courant et extrait tous les noms de classe et d'identifiants, puis nous indique si affiche l'un d'entre eux ne correspond pas au style Java.
t t t
For the program to operate correctly, you must first build a class name repository to hold all the class names in the standard Java library. You do this by moving into all the source code subdirectories for the standard Java library and running ClassScanner in each subdirectory. Provide as arguments the name of the repository file (using the same path and name each time) and the -a command-line option to indicate that the class names should be added to the repository.
t Afin que le programme s'exécute correctement, on devra d'abord construire un dépôt de noms de classes pour conserver tous les noms de classes dans la bibliothèque standard de Java. On réalise ceci en se déplaçant dans tous les sous-répertoires du code source de la bibliothèque standard Java et en exécutant ClassScanner dans chaque sous répertoire. Donnant comme arguments le nom du fichier dépositaire (utilisant le même chemin et nom chaque fois) et l'option -lign de commande -a pour indiquer que les noms de classes devront être ajoutés au dépôt.
t t t
To use the program to check your code, hand it the path and name of the repository to use. It will check all the classes and identifiers in the current directory and tell you which ones don’t follow the typical Java capitalization style.
t Afin d'utiliser le programme pour vérifier votre code, indiquez lui le chemin et le nom du dépôt à employer. Il vérifiera toutes les classes et les identifiants du répertoire courant et vous vous dira lesquels ne suivent pas le style de capitalisation Java.
t t t
You should be aware that the program isn’t perfect; there are a few times when it will point out what it thinks is a problem but on looking at the code you’ll see that nothing needs to be changed. This is a little annoying, but it’s still much easier than trying to find all these cases by staring at your code.
t Vous devrez être conscient que ce programme n'est pas parfait ; il y a quelques fois ou il signalera ce qui lui semble être un problème mais en regardant le code vous verrez qu'il n'y a rien à changer. C'est quelque peut agaçant, mais c'est tellement plus simple que d'essayer de trouver tous ces cas en vérifiant de vos yeux votre code.
t t t
t t t
t t
\\\
///
t t t
t
     
Sommaire Le site de Bruce Eckel