![](/img/trans.png)
[英]Java 7 -> Java 8: AES Causes exception: “BadPaddingException: Given final block not properly padded” in conjunction with BufferedReader & ZipStreams
[英]Java: Using BufferedReader and PrintWriter in Conjunction Causes Issues
我正在尝试通过实验和《 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();
行Profile hypro = Profile.promptedProfile();
。
所以我想问:
预先谢谢你。
PS我已经知道java.util.Scanner类,但是我想解决这个问题而不使用它。 另外,我也愿意就应该在这里实现的任何更好的编程实践提出建议。
PrintWriter
已缓冲,并且只有在以下两种情况下才会刷新自身:
flush()
,或 autoflush
参数的true
构造它, 并通过调用println()
或在传递给print()
或write()
的数据中使用\\n
或\\r\\n
来print()
行终止符。 您没有做任何这些事情。 如果希望行终止的输出在print()
之后立即出现,则需要刷新。
import java.io.*;
public class UsingPrinterWriter {
public static void main(String argv[]) {
PrintWriter output = new PrintWriter(System.out, true);
Profile hypro = Profile.promptedProfile(output);
output.print("\n");
output.flush();
output.println(hypro);
output.close();
}
}
class Profile {
private String firstName;
private String lastName;
private int age;
Profile() {
}
Profile(String firstName, String lastName, int age) {
this.firstName = firstName;
this.lastName = lastName;
this.age = age;
}
void setFirstName(String fn) {
this.firstName = fn;
}
void setLastName(String ln) {
this.firstName = ln;
}
void setAge(int a) {
this.age = a;
}
static Profile promptedProfile(PrintWriter output) {
Profile newProfile = new Profile();
BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
try {
// prompt for first name
output.println("Enter your first name: ");
output.flush();
newProfile.setFirstName(input.readLine());
// prompt for last name
output.println("Enter your last name: ");
output.flush();
newProfile.setLastName(input.readLine());
// prompt for age
output.println("Enter your age: ");
output.flush();
while (true) {
try {
newProfile.setAge(Integer.parseInt(input.readLine()));
if (newProfile.age > 0 && newProfile.age < 110) {
break;
}
throw new NumberFormatException("Out of bounds.");
} catch (NumberFormatException nfe) {
output.println("Invalid response, try again: ");
}
}
input.close();
} catch (IOException ioe) {
output.println(ioe);
}
return newProfile;
}
@Override
public String toString() {
return String.format("Profile:\n Name: %s %s\n Age: %d\n", this.firstName, this.lastName, this.age);
}
}
让我们从一些基础知识开始:
首先, 冲洗流意味着什么? ,好,这只是意味着当您刷新缓冲的流时,会清除其中的所有数据并将其发送到目标位置。 在您的代码中,刷新输出将确保将其中的所有数据发送到控制台(System.out)进行打印。
其次,流System.out是STATIC流,即您仅获得该流的一个副本,并且在关闭该流时,不能再次使用它来打印内容。
问题1 :现在,尽管您已启用自动刷新( PrintWriter output = new PrintWriter(System.out, true); // the second argument is true
),但仅在\\ r \\ n(回车换行符,CRLF)时才调用自动刷新或遇到\\ n,并且由于您的输出语句缺少这些字符,因此不会在正确的时间刷新流,因此不会显示任何提示。 当自动刷新第一次和最后一次运行时,数据一直附加到流中,直到程序结束,结果,当程序终止时,所有语句都打印在一行中。
解决方法 :如上一个答案所述,您可以使用println()
而不是print()
,也可以将缺少的字符添加到print()
调用中,例如:
output.print(new_profile.getName() + "\\r\\n")
或者,如果您想在同一行中获得输出,则可以在每个print()调用之后手动调用flush()(@EJP建议编辑)
问题2 :正如我刚才所说,System.out流是静态流,并且由于在调用hintdProfile promptedProfile()
时关闭了该流,因此无法在UsePrinterWriter类的main方法中再次使用它。 您可以在函数调用之前尝试打印其他内容,如下所示:
output.println("foo bar"); //print something here Profile hypro = Profile.promptedProfile();
您会看到foo bar
印在控制台上。
要解决的问题 :如要解决此问题,我想说的是,在使用System.out的writer对象上调用close()之前,在单个函数中打印所有内容并打印所有内容,或者可以简单地使用System.out.println();
完全避免所有这些;)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.