Javaプラットフォームでは3つの標準ストリームがサポートされます。 System.inでアクセスされる標準入力、System.outでアクセスされる標準出力、System.errでアクセスされる標準エラーです。 これらのオブジェクトは自動的に定義され、オープンする必要はありません。 標準出力と標準エラーはどちらも出力に使用します。エラー用の出力が別になっているため、ユーザーは正常な出力のみをファイルに書き込みつつ、エラー・メッセージも読むことができます。 詳細は、お使いのコマンドライン・インタプリタの資料を参照してください。
標準ストリームは文字ストリームだろうと想像されるかもしれませんが、歴史的な理由でバイト・ストリームになっています。 System.outとSystem.errはPrintStreamオブジェクトとして定義されています。 ただし、PrintStreamは技術的にはバイト・ストリームですが、内部的に文字ストリーム・オブジェクトを利用して、文字ストリームが持つ機能の多くを実装しています。
一方、System.inは文字ストリーム機能を一切持たないバイト・ストリームです。 標準入力を文字ストリームとして使用するには、次のようにSystem.inをInputStreamReaderでラップしてください。
InputStreamReader cin = new InputStreamReader(System.in);
Console型の単一の事前定義オブジェクトであり、標準ストリームのほとんどの機能に加えて、追加の機能も備えています。 コンソールは特に、安全なパスワード入力に役立ちます。 また、コンソール・オブジェクトでは、readerメソッドとwriterメソッドを使用して、本物の文字ストリームの入力ストリームと出力ストリームを扱うこともできます。
プログラムでコンソールを使用する前に、System.console()を呼び出して、コンソール・オブジェクトの取得を試みる必要があります。 コンソールを操作できる場合は、コンソール・オブジェクトが返されます。 System.console()によりNULLが返される場合は、コンソール操作は許可されていません。その理由は、OSがコンソール操作をサポートしていないか、プログラムが非インタラクティブ環境で開始されたかのいずれかです。
コンソール・オブジェクトでは、readPasswordメソッドによって、安全なパスワード入力がサポートされています。 このメソッドは、2つの方法でパスワード入力の安全性を強化します。 1つ目に、エコーを無効にして、パスワードがユーザーの画面上に表示されないようにします。 2つ目に、readPasswordはString値ではなく文字配列を返します。このため、パスワードは上書きすることができ、不要になったらすぐにメモリから削除できます。
サンプルのPasswordは、ユーザーのパスワードを変更する典型的なプログラムです。 ここでは、複数のConsoleメソッドが使用されています。
import java.io.Console;
import java.util.Arrays;
import java.io.IOException;
public class Password {
public static void main (String args[]) throws IOException {
Console c = System.console();
if (c == null) {
System.err.println("No console.");
System.exit(1);
}
String login = c.readLine("Enter your login: ");
char [] oldPassword = c.readPassword("Enter your old password: ");
if (verify(login, oldPassword)) {
boolean noMatch;
do {
char [] newPassword1 =
c.readPassword("Enter your new password: ");
char [] newPassword2 =
c.readPassword("Enter new password again: ");
noMatch = ! Arrays.equals(newPassword1, newPassword2);
if (noMatch) {
c.format("Passwords don't match. Try again.%n");
} else {
change(login, newPassword1);
c.format("Password for %s changed.%n", login);
}
Arrays.fill(newPassword1, ' ');
Arrays.fill(newPassword2, ' ');
} while (noMatch);
}
Arrays.fill(oldPassword, ' ');
}
// 仮の確認メソッド。
static boolean verify(String login, char[] password) {
// このサンプルでは、このメソッドは常にtrueを返します。
// 適切なルールに従ってパスワードを確認するように、このメソッドを修正してください。
return true;
}
// 仮の変更メソッド。
static void change(String login, char[] password) {
// 適切なルールに従ってパスワードを変更するように、このメソッドを修正してください。
}
}
Passwordクラスは、次の手順で処理を行います。
Console.readLineを呼び出して、ログイン名の入力を求めるメッセージを表示し、入力されたログイン名を読み取ります。
Console.readPasswordを呼び出して、変更する古いパスワードの入力を求めるメッセージを表示し、入力されたパスワードを読み取ります。
verifyを呼び出して、ユーザーにパスワードの変更権限があるかを確認します。 (このサンプルでは、verifyは仮のメソッドであり、常にtrueを返します。)
Console.readPasswordを呼び出して、新しいパスワードの入力を求めるメッセージを表示し、入力されたパスワードを読み取ります。これを2回行います。
changeを呼び出してパスワードを変更します。 (上記同様、changeも仮のメソッドです。)