java - 是否可以为现有的 Scanner 对象指定新的源?

标签 java java.util.scanner

对于以下代码:

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";

因为在我声明 Scanner 之后,这一行出现在 while 循环内。 为了解决这个问题,我必须在该行之后声明 Scanner,该行位于 while 循环内。 然而,我不喜欢在 while 循环内声明 Scanner 的想法,因为这将在 while 循环的每次迭代中创建一个新的 Scanner 对象。如果可能的话我愿意:

  • 在循环外声明 Scanner 对象
  • 从循环内更新 Scanner 对象的源。

基本上,重用 Scanner 对象。

如果您能帮助我,我将不胜感激。

<小时/>

编辑:我还想将whitspace传递给正在写入的文本文件,其格式与原始文本文件中采用的格式相同。

最佳答案

您无法更改 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

关于java - 是否可以为现有的 Scanner 对象指定新的源?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28617827/

相关文章:

java - 逆向工程排序算法

java - 为什么我的程序没有运行并抛出 "Exception in thread "main"java.lang.NullPointerException"

java - 如何用空格返回我的字符串值

java - 当给定高值时程序崩溃

java - 如何在 System.in 上使用多个 Scanner 对象?

java - java中的扫描器不是线程安全的吗?

java - JInternalFrame 和 JDesktopPane

java - 深拷贝 : Orika vs SerializationUtils

java - 错误 : incompatible types: String cannot be converted to int in Java

java - EasyMock 在没有匹配器的方法调用记录中抛出匹配器错误?