2011-01-18 4 views
0

Sorte d'un noob Java, et avoir retourné entre environ 6 flux différents + scanner et n'ont toujours pas trouvé un moyen de faire tout ce dont j'ai besoin. Je suis en train d'essayer d'implémenter un algorithme pour analyser un fichier qui suit une certaine syntaxe. Il y a plusieurs endroits où je dois jeter un coup d'œil au caractère suivant pour voir s'il s'agit d'une parenthèse ou d'une virgule, et aussi pour pouvoir lire les chaînes et les valeurs décimales. Je l'ai eu travailler avec un flux jusqu'à ce que j'ai essayé de lire le double. Le double n'est PAS dans un format binaire, donc DataInputStream n'est pas ce que je veux.Analyser des données mélangées avec Java

je pourrais utiliser le scanner pour son getNextFloat, mais le problème avec l'aide d'un scanner est il n'y a pas délimiteurs réel dans le fichier: (test:1.234,rightTest:5.6789)

Si je précise (,:) comme délimiteurs avec le scanner, je perdre la capacité de tester leur existence du délimiteur (I thionk, car il semble qu'il mange le délimiteur). Ces blocs peuvent être imbriqués les uns dans les autres de différentes manières, j'ai donc souvent besoin de tester le caractère suivant pour voir s'il s'agit d'une parenthèse ouvrante, puis de passer à différentes parties de la logique. C'est à dire. il forme un arbre (mais s'il vous plait, ne code pas correctement pour analyser un arbre car c'est mon devoir).

Je pourrais faire disparaître le scanner et retourner à ma solution d'origine avec un flux si je pouvais seulement comprendre comment analyser la valeur décimale. J'ai besoin de quelque chose qui fait un "lire jusqu'à ce que vous trouviez un de ces caractères" pour que je puisse dire stream.ReadUntil (",)"). Les décimales sont toujours suivies d'une virgule ou d'une parenthèse de fermeture. Comme un hack, je vais probablement lire un char à la fois. C'est la même chose que j'ai fait pour attraper la corde comme "test" et "rightTest", et c'était vraiment horrible. La seule autre option que je connais est quelque chose avec un tokenizer de chaîne, mais mon sentiment à partir des exemples est que je devrais lire le fichier entier dans une chaîne pour le marquer, en défiant essentiellement le but d'utiliser un flux. Ces fichiers peuvent être vraiment gros et juste comme exersize pour moi-même j'aime essayer de coder de telle sorte que je ne mets pas tout en mémoire si c'est inutile, même si pour cette tâche ce n'est pas vraiment important.

donc essentiellement ce que je cherche un peu d'aide sur les mécanismes du fichier IO pour pouvoir jeter un regard au caractère suivant je peux vérifier (,:) quand necesary, et ont également la capacité de lire une chaîne jusqu'à un : et lire une valeur décimale jusqu'à un : ou )

+0

= fournissez un échantillon de votre fichier –

Répondre

2

Avez-vous regardé le PushbackReader de java.io? Peeking est l'un de ses usecases. Voici un exemple.

PushbackReader pusher = new PushbackReader(reader); 
char c = (char)pusher .read(); 
// code to work with the peeked character 
pusher .unread((int)c); //push character back into the buffer 
+0

Merci, mais cela ne me rapproche pas du BufferedInputReader. Je peux jeter un coup d'oeil, mais je ne peux rien faire comme TryParseFloat(). Donc, je suis de retour à l'écriture d'un char à la fois quand je veux la chaîne ou le flotteur. – AaronLS

0

Le flux et le scanner sont les seules options acceptables? J'aurais utilisé le modèle Matcher. Par exemple cet extrait détermine le jeu de caractères d'une page html donnée et code pour le reste du contenu en utilisant ce charset:

BufferedReader in = new BufferedReader(new FileReader(new File("index.html"))); 
String inputLine; 
String returnedContent = ""; 
Pattern charsetPattern = Pattern.compile(".*<meta.*content=\"text/html;.*charset=([A-Za-z0-9\\-]*)\">.*"); 
while ((inputLine = in.readLine()) != null) { 
    if (serviceCharset == null) { 
     Matcher m = charsetPattern.matcher(inputLine); 
     if (m.find()) { 
      charset = m.group(1);//the expression included in the() is one ordered group 
     } 

    } 
    returnedContent += new String(inputLine.getBytes(), charset != null? charset : "UTF8"); 
} 
in.close(); 

Je sais que l'exemple n'a pas grand-chose à voir avec votre question, il montre à quel point pratique est regex dans ce genre de problèmes: vous lisez la ligne de fichier après ligne (donc pas de soucis sur votre tampon) et faites correspondre le texte dont vous avez besoin en utilisant des expressions régulières.

0

Vous pouvez également tenter de mapper votre fichier via un MappedByteBuffer pour y accéder (en gros) comme il s'agissait d'un tableau d'octets en mémoire.Et si vous avez besoin de le traiter comme un flux de caractères, vous pouvez l'envelopper dans un CharBuffer. Voir par exemple. here (Mappage des fichiers section).

Questions connexes