【问题标题】:Getting null value from bufferedreader从缓冲读取器获取空值
【发布时间】:2016-07-06 22:17:47
【问题描述】:

我无法理解为什么我在以下代码(输出的第 2 行)中从 bufferedreader 得到 null,而它在某些地方工作正常(输出的第 1 行)。

我已经使用了几个 system.out.println 只是为了调试目的。

虽然 BufferedReader.readLine() 仅在到达流的末尾时才返回 null,但正在提供输入(如程序下方的输入所示)。请帮助我了解获取 null 的原因并提出解决方案。

 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);
}
}

输入

输入的第一行将包含两个空格分隔的整数,分别表示 N 和 Q。

接下来的 N 行将包含字符串

接下来的 Q 行将包含一个整数或一个表示人名的字符串。根据是aString还是Integer,需要实现不同的逻辑。

enter code here

输入输出如下:

 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

【问题讨论】:

  • 正如您所说,“null 的原因”是流结束。你不是在测试它或处理它。这样做。注意不要在循环中每次都创建一个新的缓冲阅读器。您可能会以这种方式丢失数据。使用相同的。

标签: java input inputstream bufferedreader system.in


【解决方案1】:

您正试图在同一个输入流上打开多个阅读器。

当您阅读第一个 br.readLine() 中的内容时,会发生以下情况:

  • BufferedReader 有一个需要填充的内部缓冲区。它从底层InputStreamReader 调用read 方法来填充它。
  • InputStreamReader,为了将输入流中的字节转换为字符,使用StreamDecoder。所以它调用StreamDecoderread 方法。在内部,它还有一个缓冲区,它会从底层流中读取尽可能多的字节到该缓冲区中。

这意味着,一旦您阅读了一行,您还会阅读该行之外的几个字符。 StreamDecoder 的默认大小为 8K 字节缓冲区,因此它会从 System.in 读取 8K 字节(如果可用)。

如果您在交互模式下使用System.in,则每次读取只会用当时可用的字节数填充缓冲区。所以它只填充一行直到用户按下Enter 的位置,因此,当您打开其他BufferedReader 实例时,它们将获得用户输入的下一个输入。

但如果System.in 是从一个文件或其他没有在行尾阻塞的流中重定向的,它将读取整个文件(假设文件小于 8K)第一次致电readLine。该数据在BufferedReader 的缓冲区或底层StreamDecoder 的缓冲区中等待。

因此,当您在 System.in 上打开新的 BufferedReader 时,该流中没有更多数据 - 它已被第一个 BufferedReader 读取。这就是为什么不建议在单个流上打开多个阅读器的原因。

【讨论】:

    【解决方案2】:

    首先,如果您使用 io.*,则不需要前两行; 其次,如果 1 就足够了,你为什么要使用这么多流

    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();}}
    

    我没有测试代码,但它应该可以工作 我是用扫描仪做的,但你也可以使用 bufferedreader

    【讨论】:

    • 代码行不是“行”,您的答案需要大写、标点符号和语法更正。
    • 谢谢。我测试了你的代码。它工作正常。您能否告诉我使用 bufferestream 的原因是 null。
    猜你喜欢
    • 2018-03-12
    • 1970-01-01
    • 1970-01-01
    • 2012-04-18
    • 2012-03-15
    • 1970-01-01
    • 2016-01-23
    • 2013-08-03
    • 2013-11-04
    相关资源
    最近更新 更多