是否可以为现有扫描仪对象指定新源?
Is it possible to specify a new source for an existing Scanner object?
对于以下代码:
String line = new String("Hello World!");
Scanner scan = new Scanner(line);
我正在尝试将 scan
的来源从 line
更改为另一个字符串。有什么方法可以为 Scanner 对象指定新源,而不必关闭它并使用新源创建新对象?
编辑:
在使用这段代码的程序中,我使用缓冲流将文本逐行读取到程序中,使用 Scanner 对象挑选出单个单词,使用 shiftWord
方法,并使用另一个缓冲区将其写出到单独的文件中。
try(InputStream in = new FileInputStream(this.fileRead)) {
Reader reader = new InputStreamReader(in, "UTF-8");
BufferedReader buffIn = new BufferedReader(reader);
try(OutputStream out = new FileOutputStream(this.fileWrite)) {
Writer writer = new OutputStreamWriter(out, "UTF-8");
BufferedWriter buffOut = new BufferedWriter(writer);
String line = new String();
Scanner scan = new Scanner(line);
line = buffIn.readLine();
String token = new String();
String sentence;
String message = new String();
while(line != null) {
line += "/stop/";
sentence = "";
do {
token = scan.next();
sentence += (shiftWord(token) + " ");
} while(!token.endsWith("/stop/"));
message += sentence + "\n";
line = buffIn.readLine();
}
buffOut.write(message);
scan.close();
buffOut.close();
} catch (IOException x) {
System.out.println("IOException: Write Error!");
}
buffIn.close();
} catch (IOException x) {
System.out.println("IOException: Read Error!");
}
代码编译正常,但是 运行 它导致 NoSuchElementException
在这一行:
token = scan.next();
调试了一下,发现问题出在:
line += "stop";
因为在我声明扫描器之后,这一行出现在 while 循环中。
要解决这个问题,我必须在 while 循环内的这一行之后声明 Scanner。
然而,我不喜欢在 while 循环内声明 Scanner 的想法,因为这将在 while 循环的每次迭代中创建一个新的 Scanner 对象。如果可能的话,我想:
- 在循环外声明 Scanner 对象
- 从循环内更新 Scanner 对象的源。
基本上,重用扫描仪对象。
如果您能帮助我,将不胜感激。
编辑:我还想传递空格,其格式与原始文本文件与正在写入的文本文件中采用的格式相同。
您无法更改 Scanner 的基础输入流 -- 它被设计为从单个输入读取直到它为空。您可以将扫描器包裹在一个 SequentialInputStream 周围,该 SequentialInputStream 包裹在 ByteArrayInputStreams 的 LinkedList 周围,然后可以在运行时扩展它,但我很难想象这是一个好主意的情况。
在您的情况下:为什么不将扫描器直接包裹在 buffIn 周围?将扫描程序配置为在您使用它们时不忽略换行符 (useDelimiter("[\s&[^\n\r]]*")
)。这样,您只需要创建一个Scanner。
编辑:此示例使用单词边界作为分隔符:
public class ScannerExample {
public static void main(String[] args) {
Scanner s = new Scanner("this is a \n\tTest");
s.useDelimiter("\b");
while (s.hasNext()) {
String token = s.next();
System.out.println("\"" + StringEscapeUtils.escapeJava(token)
+ "\"\tapply shiftToken = " + !token.matches("\A\s+\z"));
}
}
}
输出:
"this" apply shiftToken = true
" " apply shiftToken = false
"is" apply shiftToken = true
" " apply shiftToken = false
"a" apply shiftToken = true
" \n\t" apply shiftToken = false
"Test" apply shiftToken = true
对于以下代码:
String line = new String("Hello World!");
Scanner scan = new Scanner(line);
我正在尝试将 scan
的来源从 line
更改为另一个字符串。有什么方法可以为 Scanner 对象指定新源,而不必关闭它并使用新源创建新对象?
编辑:
在使用这段代码的程序中,我使用缓冲流将文本逐行读取到程序中,使用 Scanner 对象挑选出单个单词,使用 shiftWord
方法,并使用另一个缓冲区将其写出到单独的文件中。
try(InputStream in = new FileInputStream(this.fileRead)) {
Reader reader = new InputStreamReader(in, "UTF-8");
BufferedReader buffIn = new BufferedReader(reader);
try(OutputStream out = new FileOutputStream(this.fileWrite)) {
Writer writer = new OutputStreamWriter(out, "UTF-8");
BufferedWriter buffOut = new BufferedWriter(writer);
String line = new String();
Scanner scan = new Scanner(line);
line = buffIn.readLine();
String token = new String();
String sentence;
String message = new String();
while(line != null) {
line += "/stop/";
sentence = "";
do {
token = scan.next();
sentence += (shiftWord(token) + " ");
} while(!token.endsWith("/stop/"));
message += sentence + "\n";
line = buffIn.readLine();
}
buffOut.write(message);
scan.close();
buffOut.close();
} catch (IOException x) {
System.out.println("IOException: Write Error!");
}
buffIn.close();
} catch (IOException x) {
System.out.println("IOException: Read Error!");
}
代码编译正常,但是 运行 它导致 NoSuchElementException
在这一行:
token = scan.next();
调试了一下,发现问题出在:
line += "stop";
因为在我声明扫描器之后,这一行出现在 while 循环中。 要解决这个问题,我必须在 while 循环内的这一行之后声明 Scanner。 然而,我不喜欢在 while 循环内声明 Scanner 的想法,因为这将在 while 循环的每次迭代中创建一个新的 Scanner 对象。如果可能的话,我想:
- 在循环外声明 Scanner 对象
- 从循环内更新 Scanner 对象的源。
基本上,重用扫描仪对象。
如果您能帮助我,将不胜感激。
编辑:我还想传递空格,其格式与原始文本文件与正在写入的文本文件中采用的格式相同。
您无法更改 Scanner 的基础输入流 -- 它被设计为从单个输入读取直到它为空。您可以将扫描器包裹在一个 SequentialInputStream 周围,该 SequentialInputStream 包裹在 ByteArrayInputStreams 的 LinkedList 周围,然后可以在运行时扩展它,但我很难想象这是一个好主意的情况。
在您的情况下:为什么不将扫描器直接包裹在 buffIn 周围?将扫描程序配置为在您使用它们时不忽略换行符 (useDelimiter("[\s&[^\n\r]]*")
)。这样,您只需要创建一个Scanner。
编辑:此示例使用单词边界作为分隔符:
public class ScannerExample {
public static void main(String[] args) {
Scanner s = new Scanner("this is a \n\tTest");
s.useDelimiter("\b");
while (s.hasNext()) {
String token = s.next();
System.out.println("\"" + StringEscapeUtils.escapeJava(token)
+ "\"\tapply shiftToken = " + !token.matches("\A\s+\z"));
}
}
}
输出:
"this" apply shiftToken = true
" " apply shiftToken = false
"is" apply shiftToken = true
" " apply shiftToken = false
"a" apply shiftToken = true
" \n\t" apply shiftToken = false
"Test" apply shiftToken = true