2009-05-01 9 views
37

Sono abituato allo stile c getchar(), ma sembra che non ci sia nulla di simile per java. Sto costruendo un analizzatore lessicale e ho bisogno di leggere il carattere di input per carattere.Come si legge l'input carattere per carattere in Java?

So che posso utilizzare lo scanner per scansionare un token o una linea e analizzare il token char-by-char, ma ciò sembra poco pratico per le stringhe che si estendono su più righe. C'è un modo per ottenere il prossimo carattere dal buffer di input in Java, o devo semplicemente rimuovere la classe Scanner?

L'input è un file, non la tastiera.

risposta

52

Utilizzare Reader.read(). Un valore di ritorno di -1 indica la fine del flusso; altrimenti, trasmettere a char.

Questo codice legge i dati di carattere da un elenco di argomenti di file:

public class CharacterHandler { 
    //Java 7 source level 
    public static void main(String[] args) throws IOException { 
     // replace this with a known encoding if possible 
     Charset encoding = Charset.defaultCharset(); 
     for (String filename : args) { 
      File file = new File(filename); 
      handleFile(file, encoding); 
     } 
    } 

    private static void handleFile(File file, Charset encoding) 
      throws IOException { 
     try (InputStream in = new FileInputStream(file); 
      Reader reader = new InputStreamReader(in, encoding); 
      // buffer for efficiency 
      Reader buffer = new BufferedReader(reader)) { 
      handleCharacters(buffer); 
     } 
    } 

    private static void handleCharacters(Reader reader) 
      throws IOException { 
     int r; 
     while ((r = reader.read()) != -1) { 
      char ch = (char) r; 
      System.out.println("Do something with " + ch); 
     } 
    } 
} 

La cosa brutta di codice di cui sopra è che utilizza set di caratteri di default del sistema. Ove possibile, preferisci una codifica conosciuta (idealmente, una codifica Unicode se hai una scelta). Vedi la classe Charset per ulteriori informazioni. (Se ti senti masochista, è possibile leggere this guide to character encoding.)

(Una cosa che si potrebbe desiderare di guardare fuori per sono i caratteri Unicode supplementari -. Quelle che richiedono due valori char da memorizzare Vedere la classe Character per maggiori dettagli ; questo è un caso limite che probabilmente non si applica ai compiti).

+0

Posso utilizzare il lettore con un file o solo con la tastiera? – jergason

+3

In genere si apre un FileInputStream e lo si avvolge in un InputStreamReader, specificando la codifica dei caratteri. (FileReader purtroppo non ti permette di specificare la codifica.) –

+0

Ho una domanda su questo per favore! Se sto leggendo un personaggio alla volta, perché ho bisogno di un BufferedReader? – Kareem

1

Sono disponibili diverse opzioni se si utilizza BufferedReader. Questo lettore bufferizzato è più veloce di Reader, quindi puoi avvolgerlo.

BufferedReader reader = new BufferedReader(new FileReader(path)); 
reader.read(char[] buffer); 

questo legge linea in serie di caratteri. Hai opzioni simili. Guarda la documentazione.

1

Avvolgere il lettore in un BufferedReader, che mantiene un buffer che consente letture molto più veloci in generale. Puoi quindi usare read() per leggere un singolo carattere (che dovrai cast). È anche possibile utilizzare readLine() per recuperare un'intera riga e quindi suddividerla in singoli caratteri. BufferedReader supporta anche la marcatura e la restituzione, quindi se è necessario, è possibile leggere una riga più volte.

In generale, si vuole usare un BufferedReader o BufferedInputStream sopra di qualsiasi flusso in realtà si sta utilizzando in quanto il buffer mantengono renderà più letture molto più veloce.

6

Avvolgere il flusso di input in un lettore bufferizzato, quindi utilizzare il metodo di lettura per leggere un byte alla volta fino alla fine del flusso.

import java.io.BufferedReader; 
import java.io.IOException; 
import java.io.InputStreamReader; 

public class Reader { 

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

     BufferedReader buffer = new BufferedReader(
       new InputStreamReader(System.in)); 
     int c = 0; 
     while((c = buffer.read()) != -1) { 
      char character = (char) c;   
      System.out.println(character);   
     }  
    } 
} 
13

Combinando le raccomandazioni degli altri per specificare una codifica di caratteri e il buffering dell'input, ecco quello che penso sia una risposta piuttosto completa.

Dando per scontato che hanno un oggetto File che rappresenta il file che si desidera leggere:

BufferedReader reader = new BufferedReader(
    new InputStreamReader(
     new FileInputStream(file), 
     Charset.forName("UTF-8"))); 
int c; 
while((c = reader.read()) != -1) { 
    char character = (char) c; 
    // Do something with your character 
} 
5

Un'altra opzione è quella di non leggere le cose in carattere per carattere - leggere l'intero file in memoria. Questo è utile se hai bisogno di guardare i personaggi più di una volta.Un modo banale per farlo è:

/** Read the contents of a file into a string buffer  */ 
    public static void readFile(File file, StringBuffer buf) 
     throws IOException 
    { 
    FileReader fr = null; 
    try { 
     fr = new FileReader(file); 
     BufferedReader br = new BufferedReader(fr); 
     char[] cbuf = new char[(int) file.length()]; 
     br.read(cbuf); 
     buf.append(cbuf); 
     br.close(); 
    } 
    finally { 
     if (fr != null) { 
     fr.close(); 
     } 
    } 
} 
+0

Il char [] potrebbe essere usato anche per cercare nel file in un secondo momento. Lo StringBuffer è appena usato per aggiungere l'array di caratteri allo StringBuffer e passarlo nuovamente al punto di esecuzione del richiamo. Immagino che il buf di StringBuffer sia vuoto quando entra nel metodo. –

+0

Questo è un metodo di esempio per dimostrare il concetto. Per utilizzare effettivamente la tecnica, suggerirei una libreria come Guava – David

+0

Dato che si sta già utilizzando un BufferedReader, questo potrebbe essere effettivamente più lento dell'impostazione di un segno e del ripristino del buffer del lettore. Vale la pena di ottenere le metriche sul rendimento prima di utilizzare questo. – Txangel

0

in Java 5 nuova funzione ha aggiunto che è il metodo d'esplorazione che dà la possibilità di leggere il carattere di ingresso per carattere in Java.

per esempio; per l'uso Metodo scanner import java.util.Scanner; dopo il metodo principale: define

Scanner myScanner = new Scanner (System.in); // per leggere il carattere

char any = myScanner.findInLine ("."). CharAt (0);

di memorizzare nulla singolo carattere, se si vuole più saperne di più carattere dichiarare più oggetto come anything1, anything2 ... altro esempio per la risposta si prega di controllare in mano (copia/incolla)

 import java.util.Scanner; 
    class ReverseWord { 

    public static void main(String args[]){ 
    Scanner myScanner=new Scanner(System.in); 
    char c1,c2,c3,c4; 

    c1 = myScanner.findInLine(".").charAt(0); 
     c2 = myScanner.findInLine(".").charAt(0); 
    c3 = myScanner.findInLine(".").charAt(0); 
    c4 = myScanner.findInLine(".").charAt(0); 

    System.out.print(c4); 
    System.out.print(c3); 
    System.out.print(c2); 
    System.out.print(c1); 
    System.out.println(); 

    } 
    } 
2

Se fossi in te, userei solo uno scanner e userei ".nextByte()". Puoi lanciarlo in un char e tu sei bravo.

0

Questo stamperà 1 carattere per riga dal file.

try { 

     FileInputStream inputStream = new FileInputStream(theFile); 
     while (inputStream.available() > 0) { 
      inputData = inputStream.read(); 
      System.out.println((char) inputData); 

     } 
     inputStream.close(); 
    } catch (IOException ioe) { 
     System.out.println("Trouble reading from the file: " + ioe.getMessage()); 
    } 
Problemi correlati