【问题标题】:Java read one text input with multiple newline charactersJava读取具有多个换行符的文本输入
【发布时间】:2014-07-29 23:19:51
【问题描述】:

我正在寻找一种方法来读取复制并粘贴到 IDE 或终端/cmd 中的行,这样 BufferedReader 将读取所有文本,即使它遇到换行符 ('\n) .棘手的部分是读者必须知道用户按下了回车键(这是一个换行符),但它必须继续读取输入字符串中的所有字符,直到到达最后一个'\n'

有没有办法做到这一点(例如使用 InputStreamReader 或其他东西)?

回答:

public static void main(String[] args) {
    InputStreamReader reader = new InputStreamReader(System.in);
    StringBuilder sb = new StringBuilder();

    int ch;

    System.out.println("Paste text below (enter or append to text \"ALT + 1\" to exit):");

    try {
        while ((ch = reader.read()) != (char)63 /*(char)63 could just be ☺*/) {
            sb.append(ch);
        }
        reader.close();
    }catch (IOException e) {
        System.err.println(e.toString());
    }
    String in = sb.toString();
    System.out.println(in);
}

【问题讨论】:

  • 如果我的粘贴缓冲区中有一百个换行符,然后我按 Enter,我接受哪个换行符作为“最后一个”换行符?
  • 不,这是不可能的。
  • 这真是令人沮丧。我在想也许我可以告诉用户复制并粘贴到一个文本文件,然后使用 BufferedReader 的 readLine(),但这看起来很奇怪。我可以将文本粘贴到 Netbeans 的终端中,但 BufferedReader 只是不会读到第二行。每个人都确定您不能更改 BufferedReader 的目标字符(这意味着如果它读取特定字符 - 例如默认情况下的 \n - 然后终止读取)?听起来不像,但我只是想确定一下。
  • “一行有多个换行符”用语自相矛盾。
  • 如果您要粘贴到终端中,终端可能会将第一个换行符视为输入的结尾,并尝试将其余部分解释为命令。根据 shell,您必须使用类似“here document”之类的东西将整个输入传递给 Java 程序。

标签: java


【解决方案1】:

我可以看出你已经做出了努力,所以我会告诉你我的意思。当您需要从流中读取时,这是一种非常常见的模式:

char[] buffer = new char[1000];
StringBuilder sb = new StringBuilder();
int count;
// note this loop condition
while((count = reader.read(buffer)) != -1) {
    sb.append(buffer, 0, count);
}
String input = sb.toString();

【讨论】:

  • 谢谢;我试过了,它卡在某个地方。我在 while 循环中运行了一个 for 循环以打印出缓冲区中的所有字符,并且 - 显然 - 输入流读取器中的字符读取部分文本两次(都从头开始)并卡在某个循环中,例如前。我也简单地做了一段时间(真的){}`,在里面做了count = reader.read(buffer); if (count = -1) break; else Sys..println(count);,它打印了 28 并且没有继续。怎么不继续了?
  • 我让它读取所有内容,如果我在 while reader.read() != -1 循环中有一个打印语句,则只打印一次,但它仍然卡在最后。我不知道为什么。
  • 我无法理解您所说的内容。发布修改后的代码?
  • 问题在于 inputstreamreader 正在等待对它说“嘿,你已关闭”或“嘿,没有更多输入来自此;你应该关闭”,因为它以为会有更多的输入,它一直在等待。所以,我通过让用户(希望他们会 - 它真的只是我在使用它 - 正在使用 Windows)在最后输入一个笑脸(ALT + 1)然后按 Enter 来解决这个问题。这终止了循环。修改后的代码在我的回答部分上面。
【解决方案2】:

好吧,我没有在 Stack Overflow 上看到这个,所以我想我会问,我不知道 InputStreamReader 是否可以工作......但我想它可以。所以,如果你想阅读有一堆换行符的文本,你必须使用InputStreamReader

这是一个实现Reader 的类(它实现了readablecloseable 并有一个方法(read(chBuf))允许您将输入流读取到缓冲区字符(一个数组)chBuf。我用来测试的代码如下:

public static void main(String[] args) {
    String in = "";

    InputStreamReader reader = new InputStreamReader(System.in);

    System.out.println("paste text with multiple newline characters below:");

    try {
        char chs[] = new char[1000];
        int n;
        while (reader.read(chs) != -1) {
            for (int i = 0; i < chs.length; i++) {
                char ch = chs[i];
                if (ch == '\u0000') {
                    break;
                } 
                in += chs[i];
            }
            System.out.println(in);
        }
        System.out.print(".");
    } catch (IOException e) {
        System.err.println(e.toString());
    }

    System.out.println(in);
}

这行得通……有点。它将输入的文本打印一次半。

【讨论】:

  • 好的,它连续工作了很多次,但现在效果不太好。它甚至无法阅读整个内容。我摆脱了if (chs[i] == '\u0000') { break; },似乎在某个时刻,随机索引后的所有字符都转换为空字符......我不知道为什么。
  • InputStreamReader 实现Reader。它不扩展InputStream。您遇到了问题,因为 read(char[]) 不能保证读取所有可用的输入。您应该循环调用它,直到它返回-1。为 null 的数组元素尚未转换为 null;它们只是从未设置为其他任何内容,因为读者没有深入了解您的输入。
  • 我不知道你在循环中这样做是什么意思。这似乎只是从输入文本的开头填满了 char 缓冲区,并多次打印输入的一半。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-08-17
相关资源
最近更新 更多