やあ!今日のレッスンは便宜上 2 つの部分に分けられます。以前に触れた古いトピックをいくつか繰り返し、いくつかの新機能について検討します :) 最初のトピックから始めましょう。
BufferedReader
あなたはすでに何度も授業を受けています。この言葉を忘れる暇がなかったことを願っています。
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
System.in
さらに読み進める前に、各コンポーネント ( 、InputStreamReader
、BufferedReader
) が何を担当し、なぜそれが必要なのかを 思い出してください。覚えていましたか?そうでなくても、心配する必要はありません。:) 何かを忘れた場合は、リーダー クラス専用のこのレッスンをもう一度読んでください。それぞれができることを簡単に思い出してみましょう。 System.in
— これはキーボードからデータを受信するためのストリームです。 原理的には、テキストを読むために必要なロジックを実装するにはこれだけで十分です。ただし、覚えているように、System.in
文字ではなくバイトのみを読み取ることができます。
public class Main {
public static void main(String[] args) throws IOException {
while (true) {
int x = System.in.read();
System.out.println(x);
}
}
}
このコードを実行してキリル文字「Й」を入力すると、出力は次のようになります。
Й
208
153
10
キリル文字はメモリ内で 2 バイトを占有し、画面に表示されます。数値 10 は、改行文字、つまり Enter キーを押したときの改行文字を 10 進数で表したものです。バイトを読むのはとても楽しいので、使用するのはSystem.in
あまり便利ではありません。キリル文字 (およびその他の) 文字を正しく読み取るために、InputStreamReader
ラッパーとして次の文字を使用します。
public class Main {
public static void main(String[] args) throws IOException {
InputStreamReader reader = new InputStreamReader(System.in);
while (true) {
int x = reader.read();
System.out.println(x);
}
}
}
同じ文字「Й」を入力しますが、今回は結果が異なります。
Й
1049
10
InputStreamReader
2 バイト (208 と 153) を 1 つの数値 1049 に変換します。これが文字を読み取ることの意味です。1049 はキリル文字の「Й」に対応します。これが真実であると簡単に納得できます。
public class Main {
public static void main(String[] args) throws IOException {
char x = 1049;
System.out.println(x);
}
}
コンソール出力:
Й
そしてforBufferedReader
(そして一般的にもBufferedAnythingYouWant
)、バッファリングされたクラスはパフォーマンスを最適化するために使用されます。データ ソース (ファイル、コンソール、Web リソース) へのアクセスは、パフォーマンスの点で非常に高価です。そこで、アクセス数を減らすために、BufferedReader
専用のバッファにデータを読み込んで蓄積し、そこからデータを取得します。その結果、データ ソースへのアクセス回数が大幅に削減される可能性があります。のもう 1 つのBufferedReader
機能と通常の よりも優れている点は、個々の数値ではなくデータ行全体を読み取るInputStreamReader
非常に便利な方法です。readLine()
もちろん、これは大きなテキストを扱うときに非常に便利です。行の読み取りは次のようになります。
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
String s = reader.readLine();
System.out.println ("The user entered the following text:");
System.out.println(s);
reader.close();
}
}
BufferedReader+InputStreamReader is faster than InputStreamReader alone
The user entered the following text:
BufferedReader+InputStreamReader is faster than InputStreamReader alone
もちろん、BufferedReader
非常に柔軟です。作業できるのはキーボードだけではありません。たとえば、必要な URL をリーダーに渡すだけで、Web から直接データを読み取ることができます。
public class URLReader {
public static void main(String[] args) throws Exception {
URL oracle = new URL("https://www.oracle.com/index.html");
BufferedReader in = new BufferedReader(
new InputStreamReader(oracle.openStream()));
String inputLine;
while ((inputLine = in.readLine()) != null)
System.out.println(inputLine);
in.close();
}
}
ファイル パスを渡すことで、ファイルからデータを読み取ることができます。
public class Main {
public static void main(String[] args) throws Exception {
FileInputStream fileInputStream = new FileInputStream("testFile.txt");
BufferedReader reader = new BufferedReader(new InputStreamReader(fileInputStream));
String str;
while ((str = reader.readLine()) != null) {
System.out.println (str);
}
reader.close();
}
}
System.out の置き換え
ここで、これまでに触れたことのない興味深い機能を見てみましょう。覚えていると思いますが、このSystem
クラスには 2 つの静的フィールド (System.in
と ) がありますSystem.out
。これらの双子の兄弟はストリーム オブジェクトです。 System.in
ですInputStream
。そしてSystem.out
、 ですPrintStream
。今から、 について話します System.out
。クラスのソース コードにドロップするとSystem
、次のようになります。
public final class System {
……………...
public final static PrintStream out = null;
…………
}
したがって、 System.out
は単にクラスの通常の静的変数ですSystem
。これには何も魔法はありません :)out
変数は参照ですPrintStream
。ここに興味深い質問があります。 がSystem.out.println()
実行されると、出力が他の場所ではなくコンソールに正確に送信されるのはなぜですか? そして、これを何らかの形で変えることはできるのでしょうか?たとえば、コンソールからデータを読み取り、テキスト ファイルに書き込むとします。System.out
追加のリーダークラスとライタークラスではなく、単純にこれを何らかの方法で実装することは可能ですか ? System.out
確かに、それは :) そして、変数が修飾子でマークされている場合でも、それを行うことができますfinal
。 では、これを実現するには何が必要でしょうか? まず第一に、PrintStream
現在のオブジェクトを置き換える新しいオブジェクトが必要です。現在のオブジェクト。System
デフォルトでは、このクラスは私たちの目的には役立ちません。コンソールを指します。データの「宛先」であるテキスト ファイルを指す新しいファイルを作成する必要があります。次に、変数に新しい値を割り当てる方法を理解する必要がありますSystem.out
。変数には マークが付けられているため、単純な代入演算子は使用できませんfinal
。 最後から逆算してみましょう。たまたま、System
クラスには必要なメソッドがありますsetOut()
。オブジェクトを取得しPrintStream
、それを出力先として設定します。それこそが私たちに必要なことなのです!あとはPrintStream
オブジェクトを作成するだけです。これも簡単です:
PrintStream filePrintStream = new PrintStream(new File("C:\\Users\\Username\\Desktop\\test.txt"));
完全なコードは次のようになります。
public class SystemRedirectService {
public static void main(String arr[]) throws FileNotFoundException
{
PrintStream filePrintStream = new PrintStream(new File("C:\\Users\\Username\\Desktop\\test.txt"));
/* Save the current value of System.out in a separate variable so that later
we can switch back to console output */
PrintStream console = System.out;
// Assign a new value to System.out
System.setOut(filePrintStream);
System.out.println("This line will be written to the text file");
// Restore the old value of System.out
System.setOut(console);
System.out.println("But this line will be output to the console!");
}
}
その結果、最初の文字列がテキスト ファイルに書き込まれ、2 番目の文字列がコンソールに表示されます :) このコードを IDE にコピーして実行できます。テキスト ファイルを開くと、文字列が正常に書き込まれていることがわかります :) これで、レッスンは終了です。今日は、ストリームとリーダーの操作方法を思い出しました。私たちはそれらが互いにどのように異なるかを思い出し、System.out
ほぼすべてのレッスンで使用した のいくつかの新しい機能について学びました :) 次のレッスンまで!
GO TO FULL VERSION