web-dev-qa-db-fra.com

Lire toutes les lignes avec BufferedReader

Je veux taper un texte de plusieurs lignes dans la console en utilisant un BufferedReader et quand je frappe "Entrée" pour trouver la somme de la longueur du texte entier. Le problème est qu’il semble que je vais entrer dans une boucle infinie et que j’appuie sur "Enter", le programme ne se termine pas. Mon code est ci-dessous:

InputStreamReader instream = new InputStreamReader(System.in);
BufferedReader buffer = new BufferedReader(instream);

    line= buffer.readLine();

    while (line!=null){
        length = length + line.length();
        line= buffer.readLine();
    }

Pourriez-vous s'il vous plaît me dire ce que je fais mal?

17
deadpixels

La façon idiomatique de lire toutes les lignes est while ((line = buffer.readLine()) != null). En outre, je suggérerais une instruction try-with-resources . Quelque chose comme

try (InputStreamReader instream = new InputStreamReader(System.in);
        BufferedReader buffer = new BufferedReader(instream)) {
    long length = 0;
    String line;
    while ((line = buffer.readLine()) != null) {
        length += line.length();
    }
    System.out.println("Read length: " + length);
} catch (Exception e) {
    e.printStackTrace();
}

Si vous souhaitez terminer la boucle lorsque vous recevez une ligne vide, ajoutez un test pour cela dans la boucle while.

while ((line = buffer.readLine()) != null) {
    if (line.isEmpty()) {
        break;
    }
    length += line.length();
}

JLS-14.15. La déclaration break dit

Une instruction break transfère le contrôle hors d'une instruction englobante. 

23
Elliott Frisch

Une ligne de code utilisant Java 8: 

line =  buffer.lines().collect(Collectors.joining());
51
Russel Yang

Lorsque vous appuyez uniquement sur Entrée, le retour de buffer.readLine(); n'est pas null, il s'agit d'une chaîne vide.

Par conséquent, vous devriez changer line != null en !line.equals("") (Vous pouvez également le changer en line.length() > 0)

Maintenant, votre code ressemblera à ceci:

InputStreamReader instream = new InputStreamReader(System.in);
BufferedReader buffer = new BufferedReader(instream);

line = buffer.readLine();

while (!line.equals("")){
    length = length + line.length();
    line = buffer.readLine();
}

Cela devrait résoudre votre problème. J'espère que cela a aidé! :)

4
Stephen Buttolph

line ne sera pas nul lorsque vous appuyez sur entrée; ce sera une chaîne empty.

Prenez note de ce que BufferedReader JavaDoc dit à propos de readLine():

Lit une ligne de texte. Une ligne est considérée comme terminée par un saut de ligne ('\ n'), un retour chariot ('\ r') ou un retour chariot suivi immédiatement par un saut de ligne.

Et readLine() renvoie:

Une chaîne contenant le contenu de la ligne, n'incluant pas les caractères de fin de ligne, ou null si la fin du flux est atteinte

Ainsi, lorsque vous appuyez sur [Entrée], vous attribuez à la BufferedReader une nouvelle ligne contenant uniquement \n, \r ou \r\n. Cela signifie que readLine() retournera une chaîne vide.

Alors essayez quelque chose comme ceci à la place:

InputStreamReader instream = new InputStreamReader(System.in);
BufferedReader buffer = new BufferedReader(instream);

line = buffer.readLine();

while( (line != null) && (!line.isEmpty()) ){
    length = length + line.length();
    line = buffer.readLine();
}
3
dbank

Réponse Snarky: ce que vous faites mal, c'est créer 2 objets en Java pour faire quelque chose ... Si vous effectuez une recherche, vous pouvez probablement trouver quelques classes supplémentaires qui étendent BufferedReader ou ExtendedBufferReader, etc. .

Maintenant que je tire cela de mon système: réponse plus utile. System.in est fermé lorsque vous entrez EOF, qui correspond à Control-D sous Linux et, je pense, à MacOS, et je pense Control-Z plus, entrez sous Windows. Si vous souhaitez vérifier l'entrée (ou plus précisément deux entrées), l'une pour terminer la dernière ligne et l'autre pour indiquer que vous avez terminé, ce qui correspond essentiellement à la façon dont http gère la détermination du moment où les en-têtes http sont terminés et l'heure de la fin le corps de http, alors la solution de @dbank devrait être une option viable avec un correctif mineur que je vais essayer de faire pour déplacer le prédicat! inside dans le prédicat tant au lieu de! while.

(Edit # 2: readLine réalisé supprime la nouvelle ligne, donc une ligne vide "" au lieu de la nouvelle ligne, mon code est dévolu à une autre réponse avec le bit EOF comme réponse plutôt que comme commentaire)

Edit ... c'est bizarre, @dbank avait répondu pendant que je tapais ma réponse, et j'aurais arrêté si je n'avais pas mentionné l'option EOF. Pour répéter son code de mémoire avec l'édition que j'allais faire:

InputStreamReader instream = new InputStreamReader(System.in);
BufferedReader buffer = new BufferedReader(instream);

    line= buffer.readLine();
    while (line != null && !line.equals("")){
        length = length + line.length();
        line= buffer.readLine();
    }
0
Foon

Depuis Java 8, vous pouvez utiliser la méthode BufferedReader#lines directement sur un lecteur en mémoire tampon.

    try (InputStreamReader in = new InputStreamReader(System.in);
         BufferedReader buffer = new BufferedReader(in)) {
        final int length = buffer.lines().mapToInt(String::length).sum();
        System.out.println("Read length: " + length);
    } catch (Exception e) {
        e.printStackTrace();
    }
0
Grzegorz Gajos

Placez toutes les lignes dans le tableau String []. et la seconde méthode récupère le nombre de lignes contenues dans le fichier texte. J'espère que cela pourrait être utile à n'importe qui ..

public static void main(String... args) throws IOException {
    String[] data = getLines();
    for(String v : data) {
        out.println(v);
    }
}

public static String[] getLines() throws IOException {
    BufferedReader bufferReader = new BufferedReader(new FileReader("C:\\testing.txt"));
    String line = bufferReader.readLine(); 
    String[] data = new String[getLinesLength()];
    int i = 0;
    while(line != null) {
        data[i] = line; 
        line = bufferReader.readLine();
        i++;
    }
    bufferReader.close();
    return data;
}

public static int getLinesLength() throws IOException {
    BufferedReader bufferReader = new BufferedReader(new FileReader("C:\\testing.txt"));
    String line = bufferReader.readLine(); 
    int size = 0;
    while(line != null) {
        size += 1;
        line = bufferReader.readLine();
    }
    bufferReader.close();
    return size;
}
0
Snow Bases