1

I am not able to understand why I am getting null from bufferedreader in following code (2nd line of output), while it worked fine at some places (1st line of output).

I have used several system.out.println's just for debugging purpose.

Although the BufferedReader.readLine() returns null only when the end of the stream is reached, the input is being provided (as shown in input below the program). Please help me in getting the reason of getting null and suggest a solution.

 import java.io.BufferedReader;
 import java.io.InputStreamReader;
 import java.util.*;
 import java.lang.Integer;
 import java.io.*;

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

     //* Read input from stdin and provide input before running
    List a2=new ArrayList();
    String[] a1=new String[2];
    int count=0;
    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    String line = br.readLine();
    /*for (String retval: line.split(" "))
        a2.add(retval);*/
    a1=line.split(" ");
    //System.out.println("here 0"+a1[0]+" "+a1[1]);
    /*int N = Integer.parseInt((a2.get(0)).toString());
    int Q= Integer.parseInt((a2.get(1)).toString());*/
    int N = Integer.parseInt(a1[0].toString());
    int Q= Integer.parseInt(a1[1].toString());

        System.out.println("here xxxxxxxx" + N +" " +Q);
    String[] names=new String[N];
    for(int i=0;i<N;i++){
        //names[i]  =   (new BufferedReader(new InputStreamReader(System.in))).readLine();

        BufferedReader br1 = new BufferedReader(new InputStreamReader(System.in));
    names[i] = br1.readLine();

    /*Scanner sc=new Scanner(System.in);  
    names[i]=sc.nextLine();*/
    }
   System.out.println("here 111" + names[0]);
   for(int i=0;i<Q;i++) {
    br = new BufferedReader(new InputStreamReader(System.in));
    String line1 = br.readLine();
    try{
         System.out.println("here 1" + line1);

        int M = Integer.parseInt(line1);
        System.out.println("here 2");
        if(M<=20){
            System.out.println("here 3");
            count++;
        }
    }
    catch(Exception e){
        System.out.println("here 4");
        if(!((Arrays.asList(names)).contains(line))){
            System.out.println("here 5");
            count++;
        }

    }
   }

    System.out.println(count);
}
}

Input

First line of the input will contain two space separated integers denoting N and Q.

Next N lines will contain strings

Next Q lines will contain either an integer or a string denoting the name of a person. Different logics have to be implemented depending on whether it is aString or an Integer.

enter code here

Inputs and outputs are as follows:

 Input:
 2 4
 pranjul
 sachin
 21
 19
 pranjul
 vipul

 Output:
 here xxxxxxxx2 4
 here 111null
 here 1null
 here 4
 here 5
 here 1null
 here 4
 here 5
 here 1null
 here 4
 here 5
 here 1null
 here 4
 here 5
 4
Flying disk
  • 120
  • 7
  • The 'reason of null' is end of stream, just as you said. You aren't testing for it or handling it. Do so. NB Don't keep creating a new buffered reader every time around the loop. You can lose data that way. Use the same one. – user207421 Mar 20 '16 at 12:41

2 Answers2

1

You are trying to open more than one reader on the same input stream.

When you read the contents in your first br.readLine(), here is what happens:

  • The BufferedReader has an internal buffer it needs to fill up. It calls the read method from the underlying InputStreamReader in order to fill it.
  • The InputStreamReader, in order to convert the bytes in the input stream into characters, uses a StreamDecoder. So it calls that StreamDecoder's read method. Internally, it also has a buffer, and it reads as many bytes as it can from the underlying stream into that buffer.

This means that as soon as you read one line, you also read several characters beyond that line. The default size is of the StreamDecoder byte buffer is 8K, so it reads 8K bytes from System.in if they are available.

If you use System.in in interactive mode, each read only fills the buffer with as many bytes as are available right then. So it fills just one line up to the point where the user pressed Enter and so, when you open your other BufferedReader instances, they will get the next input the user enters.

But if System.in is redirected from a file or other stream where it is not blocking on end-of-line, it will read the entire file (assuming the file is smaller than 8K) on the first call to readLine. That data waits in that BufferedReader's buffer or the underlying StreamDecoder's buffer.

So when you open a new BufferedReader on System.in, there is no more data in that stream - it has already been read by the first BufferedReader. That's why it's not recommended to open more than one reader on a single stream.

RealSkeptic
  • 33,993
  • 7
  • 53
  • 79
0

first of all you dont need the first two rows if you use the io.*; secondly why did you use so many streams, if 1 is enough

import java.util.*;
 import java.lang.Integer;
 import java.io.*;

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

List a2=new ArrayList();
int count=0;
Scanner br = new Scanner(System.in);
String line = br.nextLine();

String[] a1=line.split(" ");
int N = Integer.parseInt(a1[0]);
int Q= Integer.parseInt(a1[1]);

    System.out.println("here xxxxxxxx" + N +" " +Q);
String[] names=new String[N];
for(int i=0;i<N;i++){
 names[i]=br.nextLine();
}
System.out.println("here 111" + names[0]);
for(int i=0;i<Q;i++) {
String line1 = br.nextLine();
try{
     System.out.println("here 1" + line1);

    int M = Integer.parseInt(line1);
    System.out.println("here 2");
    if(M<=20){
        System.out.println("here 3");
        count++;
    }
}
catch(Exception e){
    System.out.println("here 4");
    if(!((Arrays.asList(names)).contains(line))){
        System.out.println("here 5");
        count++;         }    }   }
System.out.println(count);
br.close();}}

i didnt test the code but it should work i did it with scanner but you can use bufferedreader aswell

Flying disk
  • 120
  • 7
KennyMD
  • 11
  • 1
  • Lines of code are not 'rows', and your answer needs to be capitalized, punctuated, and grammatically corrected. – user207421 Mar 20 '16 at 12:43
  • Thanks. I tested your code. Its working fine. Could you please tell me the reason why using bufferestream is giving null. – Flying disk Mar 20 '16 at 12:45