提问人:arnobpl 提问时间:6/14/2017 更新时间:4/14/2021 访问量:1072
Java Scanner 用于在不前进位置的情况下查看某些内容(int、double、line 等)
Java Scanner for peeking something (int, double, line, etc) without advancing position
问:
我们知道 Java 类的 、 、 等 方法解析某些东西(int、double、line 等)并推进扫描器的位置。但我只需要一种方法来解析某些东西,而不是为了提升位置。这意味着,我需要一些方法来实现诸如 、 、 等方法。nextInt()
nextDouble()
nextLine()
Scanner
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)
}
Here 解析该行,直到找到行分隔符,然后将该位置推进到下一行的开头。如果为 false,则在方法中根本无法读取 中分配的字符串。必须以某种方式避免它。我可能会将变量传递给 ,但它会使代码变得混乱。marker = in.nextLine();
marker.equals(endSocketMarker)
marker
respond(in, out, clientIp)
marker
respond(in, out, clientIp)
有没有更好的方法来实现我的目标?
答:
如果此扫描程序的输入中有另一个标记,则该方法返回 true。此方法可能会在等待输入扫描时阻塞。扫描仪不会前进到任何输入。java.util.Scanner.hasNext()
这里有一个例子,hasNext() 例子
评论
hasNext()
如果扫描程序的输入中有另一个令牌,但不返回该令牌,则方法返回 true。但是我需要该令牌,而无需推进扫描仪的位置。我想,我无法向你解释我的问题。
next
nextInt()
nextDouble()
nextLine()
为此,您可以通过 a 和相应的 hasNext
检查下一个令牌。这样你就不会推进仓位,但你可以窥视下一个代币(通过它的模式)......Pattern
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() + "\".");
}
}
将 转换为提供给 的 的意义只是为了演示如何将 与 一起使用。否则,我可以简单地直接向 的构造函数提供。testString
InputStream
Scanner
InputStream
Scanner
testString
Scanner
我也在考虑提供 with a 并在后者上使用 /,但经过一些测试和一些搜索,我发现内部使用缓冲区。这意味着 的缓冲区被来自 的所有数据填满,从而推进了 的位置,而不让我们标记正确的位置。即使您每次都创建一个新对象,使用相同的对象也会产生相同的效果,因为无论如何都会高级。Scanner
BufferedInputStream
mark
reset
Scanner
Scanner
BufferedInputStream
BufferedInputStream
Scanner
BufferedInputStream
BufferedInputStream
评论