こんにちは!本日の講義は2部に分かれております。以前にすでに触れた古いトピックのいくつかを繰り返し、いくつかの新機能を見ていきます :) 最初のトピックから始めましょう。繰り返しは学習の母です:) あなたはすでに のようなクラスを使用しています
BufferedReader
。このコマンドをまだ忘れていないことを願っています。
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
System.in, InputStreamReader, BufferedReader
さらに読み進める前に、各コンポーネント ( ) が何を担当し、何に必要なのか を思い出してください。起こりました?そうでなくても、心配しないでください :) この時点で何かを忘れてしまった場合は、読者向けにこの講義をもう一度読んでください。それぞれが何ができるかを簡単に思い出してみましょう。 System.in
キーボードからデータを受信するためのスレッドです。原則として、テキストを読むロジックを実装するには、1 つで十分です。ただし、覚えているとおり、System.in
読み取ることができるのはバイトのみであり、文字は読み取ることができません。
public class Main {
public static void main(String[] args) throws IOException {
while (true) {
int x = System.in.read();
System.out.println(x);
}
}
}
このコードを実行してコンソールに文字「Y」を入力すると、出力は次のようになります。
Й
208
153
10
キリル文字はメモリ内で 2 バイトを占め、画面に表示されます (数字の 10 は改行、つまり Enter キーを押すことのバイト表現です)。バイトを読み取るのは非常に楽しいので、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);
}
}
}
同じ文字「Y」をコンソールに入力すると、今回の結果は異なります。
Й
1049
10
InputStreamReader
読み取られた 2 つのバイト (208、153) を 1 つの数値 1049 に変換します。これは文字単位の読み取りです。1049 は文字「Y」に対応しており、簡単に確認できます。
public class Main {
public static void main(String[] args) throws IOException {
char x = 1049;
System.out.println(x);
}
}
コンソール出力:
Й
BufferedReader
'a (および一般的に - BufferedAnything) に関しては、パフォーマンスを最適化するためにバッファリングされたクラスが使用されます。データ ソース (ファイル、コンソール、インターネット上のリソース) へのアクセスは、パフォーマンスの点でかなり負荷の高い操作です。したがって、このような呼び出しの数を減らすために、BufferedReader
特別なバッファーにデータを読み取って蓄積し、後でそこからデータを受信できるようにします。その結果、データ ソースへの呼び出し数が数分の 1、あるいは数十分の 1 にまで削減されます。BufferedReader
「 a と通常の 」に対するもう 1 つの追加機能は、データを個々の数値としてではなく文字列全体として読み取る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("Пользователь ввел следующий текст:");
System.out.println(s);
reader.close();
}
}
BufferedReader+InputStreamReader работает быстрее, чем просто InputStreamReader
Пользователь ввел следующий текст:
BufferedReader+InputStreamReader работает быстрее, чем просто InputStreamReader
もちろん、BufferedReader
これは非常に柔軟なメカニズムであり、キーボードだけでなく作業も可能です。たとえば、必要な URL をリーダーに渡すだけで、インターネットから直接データを読み取ることができます。
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 の置換
ここで、これまで触れなかった興味深い可能性を 1 つ見てみましょう。おそらく覚えていると思いますが、System
クラスには 2 つの静的フィールド (System.in
と )がありますSystem.out
。これらの双子の兄弟はスレッド クラス オブジェクトです。System.in
- 抽象クラスInputStream
。ASystem.out
クラスPrintStream
。ここからは具体的に についてお話していきますSystem.out
。class のソースコードにアクセスすると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"));
/*Сохраним текущее meaning System.out в отдельную переменную, чтобы потом
можно было переключиться обратно на вывод в консоль*/
PrintStream console = System.out;
// Присваиваем System.out новое meaning
System.setOut(filePrintStream);
System.out.println("Эта строка будет записана в текстовый файл");
// Возвращаем System.out старое meaning
System.setOut(console);
System.out.println("А эта строка - в консоль!");
}
}
その結果、最初の行はテキスト ファイルに書き込まれ、2 行目はコンソールに出力されます :) このコードを IDE にコピーして実行できます。テキスト ファイルを開くと、必要な行が正常に記述されていることがわかります :) これで講義は終わりです。今日、私たちはストリームとリーダーの操作方法を思い出し、それらがどのように異なるかを思い出し、System.out
ほぼすべてのレッスンで使用した新しい機能について学びました :) 次の講義でお会いしましょう!
GO TO FULL VERSION