Java:在第一个令牌之后停止扫描程序

Java:在第一个令牌之后停止扫描程序,java,string,stream,Java,String,Stream,我尝试生成System.in的自动输入,并希望能够在任意时间通过不同的扫描仪读取流中的后续令牌: // save System.in for later restoration InputStream inTemp = System.in; // create an input String input = "15 3"; // push input into InputStream InputStream bais = new ByteArrayInputStream(input.getBy

我尝试生成System.in的自动输入,并希望能够在任意时间通过不同的扫描仪读取流中的后续令牌:

// save System.in for later restoration
InputStream inTemp = System.in;

// create an input
String input = "15 3";
// push input into InputStream
InputStream bais = new ByteArrayInputStream(input.getBytes());
// deviate System.in
System.setIn(bais);

Scanner s1 = new Scanner(System.in);
// the nextInt should only read the "15" from the input
int i1 = s1.nextInt();
System.out.println("#1: " + i1 * 2);

Scanner s2 = new Scanner(System.in);
// the nextInt should read the "3" from the input
int i2 = s2.nextInt();
System.out.println("#2: " + i2 * 2);

// restore System.in
System.setIn(inTemp);
不幸的是,扫描器s1预防性地读取流的全部内容,而不是仅读取第一个令牌。因此,第二扫描器s2找到空输入

上面的代码是对实际情况的极端简化:使用扫描仪的部分不属于我的责任范围。它是由提交课程到我们的考试系统的学生创建的。我们的系统在用测试数据填充system.in后调用学生的方法。因此,我们不能影响扫描仪的使用方式。顺便说一句:关闭扫描仪不会有帮助。第一个扫描器只是从流中读取了太多的数据

实际上,我看到了一些可能的方法:

  • 在输入中放置标记,以防止扫描仪进一步读取

  • 扩展ByteArrayInputStream,使其每次尝试仅显示一个令牌。这可能意味着操作available()-方法的输出、pos属性和流的buf内容,以及跟踪扫描仪执行的读数数量。尽管如此,扫描器仍会不断请求数据,而不管它应该读取多少令牌。以前有人这样做过吗

  • 使用提供第2条(或类似内容)所述功能的不同流

  • 要求学生使用不同的方法(而不是nextInt)读取扫描仪中的数据,并按照要求进行操作。有这样的方法吗?我没找到

  • 我已经开始通过扩展ByteArrayInputStream来操纵行为,但并没有走得太远,因为我认为这可能是一种概念上过于复杂的方法

    感谢您的帮助

    致以最良好的祝愿,
    托马斯

    尝试在第一次读取后关闭第一台扫描仪。这将关闭第一台扫描仪,并允许第二台扫描仪读取下一个变量。

    我认为答案是。。。没有

    没有办法阻止
    扫描仪
    提前读取和缓冲字符,也没有办法强迫它“放回”已缓冲的字符。(事实上,除非您从支持标记/重置或回推方法的源读取数据,否则无法“放回”字符。)

    您需要重新考虑您的测试方法。重新使用
    扫描仪
    实例


    另一种选择是实现自己版本的
    扫描仪
    。。。这确实允许您以某种方式“放回”缓冲字符。

    这也将关闭底层流-此处为System.in-并且任何方法都无法从此流中读取任何内容,因为:“当扫描仪关闭时,如果源实现可关闭接口,它将关闭其输入源。”(取自),我可能会构建自己版本的
    ByteArrayInputStream
    ,这样每次调用
    Scanner.nextInt()
    时只显示一个令牌。这样做,我不需要改变学生的设置,也不需要教他们一些特殊的编码约定,只是为了满足我们的测试方法。最困难的部分可能是区分一个
    扫描器
    提前读取和一个
    扫描器
    读取下一个标记。我想到了这种方法。“最困难的部分可能是区分扫描仪读取前方和扫描仪读取下一个标记。”的确如此。该部分只能通过修改
    扫描仪来完成。就我所知