首页 > 解决方案 > Java:结合使用 BufferedReader 和 PrintWriter 会导致问题

问题描述

我正在尝试通过实验和“Java2:完整参考(第 5 版)”一书了解 Java 的 io 包。下面,我尝试制作一个非常简单的程序,使用 BufferedReader 实例获取一些输入,并使用 PrintWriter 实例提供一些简单的控制台输出。

package io;

import java.io.*;

public class UsingPrinterWriter {
    public static void main(String argv[]) {
        PrintWriter output = new PrintWriter(System.out, true);
        Profile hypro = Profile.promptedProfile();
        output.print(hypro);
        output.close();
        return;
    }
}

class Profile {
    private String first_name;
    private String last_name;
    private int age;

    Profile() {}

    Profile(String first_name, String last_name, int age) {
        this.first_name = first_name;
        this.last_name = last_name;
        this.age = age;
    }

    void setFirstName(String fn) {
        this.first_name = fn;
        return;
    }

    void setLastName(String ln) {
        this.last_name = ln;
        return;
    }

    void setAge(int a) {
        this.age = a;
        return;
    }

    static Profile promptedProfile() {
        Profile new_profile = new Profile();

        // create the writer and reader
        PrintWriter output = new PrintWriter(System.out, true);
        BufferedReader input = new BufferedReader(new InputStreamReader(System.in));

        try {
            // prompt for first name
            output.print("Enter your first name: ");
            new_profile.setFirstName(input.readLine());

            // prompt for last name
            output.print("Enter your last name: ");
            new_profile.setLastName(input.readLine());

            // prompt for age
            output.print("Enter your age: ");
            while(true) {
                try {
                    new_profile.setAge(Integer.parseInt(input.readLine()));
                    if(new_profile.age > 0 && new_profile.age < 110) {
                        break;
                    }
                    throw new NumberFormatException("Out of bounds.");
                } catch(NumberFormatException nfe) {
                    output.print("Invalid response, try again: ");
                }
            }
            input.close();          
        } catch (IOException ioe) {
            output.println(ioe);
        } finally {
            output.close();
        }

        return new_profile;
    }

    @Override
    public String toString() {
        return String.format("Profile:\n  Name: %s %s\n  Age: %d\n", this.first_name, this.last_name, this.age);
    }
}

问题1:当我运行这个(使用Eclipse IDE)时,我得到的输出是一个空白终端,一旦我输入一个字符串、另一个字符串和一个有效整数,在换行符中一个接一个,(然后)我执行 output.print(...) 的提示行被打印出来。这是一个例子来说明我的意思:

first
last
20
Enter your first name: Enter your last name: Enter your age:

问题 2:行:output.print(hypro);不会被打印。行后的任何东西Profile hypro = Profile.promptedProfile();

所以我想问:

  1. 这里发生了什么(我似乎缺少关于这些 io 类的概念性知识)?
  2. 我能做些什么来解决这些问题?

提前谢谢你。

PS 我已经知道 java.util.Scanner 类,但我想在不使用它的情况下解决这个问题。此外,我愿意接受有关我应该在这里实现的任何更好的编程实践的建议。

标签: javaio

解决方案


PrintWriter被缓冲,并且不会自行刷新,直到:

  1. 你打电话flush(),或
  2. true您使用forautoflush参数构造了它,通过调用println()或在传递给 or 的数据中包含\nor来打印行终止符。\r\nprint()write()

你没有做任何这些事情。如果您希望在 之后立即出现行终止输出print(),则需要刷新。


推荐阅读