Java扫描器,用于在不移动位置的情况下偷看东西(int、double、line等)

Java扫描器,用于在不移动位置的情况下偷看东西(int、double、line等),java,java.util.scanner,bufferedreader,inputstreamreader,Java,Java.util.scanner,Bufferedreader,Inputstreamreader,我们知道JavaScanner类的NextTint()、nextDouble()、nextLine()等方法解析某些内容(int、double、line等)并提升扫描仪的位置。但我只需要一种方法来解析某些东西,而不需要推进位置。这意味着,我需要一些方法来实现类似peekInt(),peekDouble(),peekLine()等方法 下面是一个例子,说明为什么它可能是必要的。假设我有一个抽象类Server,它有一个抽象方法respond(Scanner-in、PrintWriter-out、St

我们知道Java
Scanner
类的
NextTint()
nextDouble()
nextLine()
等方法解析某些内容(int、double、line等)并提升扫描仪的位置。但我只需要一种方法来解析某些东西,而不需要推进位置。这意味着,我需要一些方法来实现类似
peekInt()
peekDouble()
peekLine()
等方法

下面是一个例子,说明为什么它可能是必要的。假设我有一个抽象类
Server
,它有一个抽象方法
respond(Scanner-in、PrintWriter-out、String-clientIp)
,由其他类实现。以下是代码的一部分:

public abstract class Server {
    // ... (some initialization variables)

    public static final String endSocketMarker = "END";

    public final void runServer() {
        // ... (multithreading code)

        clientSocket = serverSocket.accept();
        Scanner in = new Scanner(new BufferedReader(new InputStreamReader(clientSocket.getInputStream())));
        PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);

        String clientIp = in.nextLine();
        String marker = "";
        do {
            respond(in, out, clientIp); // call abstract method
            marker = in.nextLine(); //TODO: find a way so that input line is peeked (but not skipped)
        } while(!marker.equals(endSocketMarker));

        // ... (close client socket)
    }

    protected abstract void respond(Scanner in, PrintWriter out, String clientIp);

    // ... (other methods)
}
此处
marker=in.nextLine()解析该行,直到找到行分隔符,然后将位置前进到下一行的开头。如果
marker.equals(endSocketMarker)
为false,则在
marker
中指定的字符串根本无法在
respond(in,out,clientIp)
方法中读取。必须设法避免。我可以将变量
marker
传递到
respond(in、out、clientIp)
,但这会使代码变得混乱


有没有更好的方法来实现我的目标?

如果此扫描仪的输入中有另一个令牌,则
java.util.Scanner.hasNext()
方法将返回true。此方法在等待输入扫描时可能会阻塞。扫描仪不会超过任何输入

这里有一个例子,

您可以通过使用相应的。通过这种方式,您不会推进位置,但您可以窥视下一个标记(通过其模式)

testString
转换为
InputStream
并提供给
Scanner
的点仅用于演示如何将
InputStream
Scanner
一起使用。否则,我可以直接将
testString
提供给
扫描器的构造函数



我还考虑为
扫描仪
提供一个
缓冲输入流
,并在后者上使用
标记
/
重置
,但经过一些测试和一点搜索后,我发现
扫描仪
内部使用了一个缓冲区。这意味着
扫描仪
的缓冲区被来自
缓冲输入流
的所有数据填满,从而推进
缓冲输入流
的位置,而不让我们标记正确的位置。即使每次创建一个新的
Scanner
对象,使用相同的
BufferedInputStream
也会产生相同的效果,因为无论怎样,
BufferedInputStream
都会被提升。

hasNext()
方法如果扫描器的输入中有另一个令牌,但不返回该令牌,则返回true。但我需要那个标记,而不需要移动扫描仪的位置。我想,我无法向你解释我的问题。扫描器不会前进超过那个标记,而是停留在那里。所有包含
next
(例如
nextInt()
nextDouble()
nextLine()
)的方法都会提升扫描器的位置,否则,连续方法调用将始终返回相同的字符串。是一行“位置设置为下一行的开头”。这与其他方法类似。同样的问题,您解决了吗?@parser:API没有提供任何相关信息。据我记忆所及,我必须手动处理。
import java.io.ByteArrayInputStream;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Scanner;
import java.util.regex.Pattern;

public class Main {
    
    public static void main(final String[] args) {
        final Charset charset = StandardCharsets.UTF_8;
        final String endSocketMarker = "END";
        final String testString = "This is some test text.\n1234567890\n" + endSocketMarker + "\nThis is still writing...";
        final Scanner scan = new Scanner(new ByteArrayInputStream(testString.getBytes(charset)), charset.name());
        final Pattern endPattern = Pattern.compile(Pattern.quote(endSocketMarker));
        while (!scan.hasNext(endPattern))
            System.out.println("Processing input, with first line being: \"" + scan.nextLine() + "\".");
        System.out.println("Reached the \"" + scan.nextLine() + "\".");
    }
}