![](/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.