こんにちは!今日の講義では、Java の入出力ストリーム、または略してJava I/O (「入出力」) について話を続けます。これは、このトピックに関する最初の講義ではありませんし、最後でもありません :) たまたま、言語としての Java は、入出力を扱う多くの機会を提供します。この機能を実装するクラスは非常にたくさんあるので、最初は混乱しないようにいくつかの講義に分けました:) 前の講義では、 BufferedReader、および抽象クラスのInputStream と OutputStream 、およびいくつかについて触れました。子孫。今日は、 FileInputStream、FileOutputStream、およびBufferedInputStreamという 3 つの新しいクラスを見ていきます。
FileOutputStream クラス
FileOutputStreamクラスの主な目的は、ファイルにバイトを書き込むことです。 複雑なことは何もありません:) FileOutputStream は、抽象OutputStreamクラスの実装の 1 つです。コンストラクターでは、このクラスのオブジェクトは、ターゲット ファイル (バイトを書き込む必要があるファイル) へのパスか、 クラスのオブジェクトのいずれかを受け取りますFile
。両方の例を見てみましょう。
public class Main {
public static void main(String[] args) throws IOException {
File file = new File("C:\\Users\\Username\\Desktop\\test.txt");
FileOutputStream fileOutputStream = new FileOutputStream(file);
String greetings = "Hi! Welcome to JavaRush - the best site for those who want to become a programmer!";
fileOutputStream.write(greetings.getBytes());
fileOutputStream.close();
}
}
オブジェクトを作成するときに、File
オブジェクトを配置するパスをコンストラクターで指定しました。事前に作成する必要はありません。存在しない場合は、プログラムが自動的に作成します。追加のオブジェクトを作成せずに、アドレスを含む文字列を渡すだけで済みます。
public class Main {
public static void main(String[] args) throws IOException {
FileOutputStream fileOutputStream = new FileOutputStream("C:\\Users\\Username\\Desktop\\test.txt");
String greetings = "Hi! Welcome to JavaRush - the best site for those who want to become a programmer!";
fileOutputStream.write(greetings.getBytes());
fileOutputStream.close();
}
}
どちらの場合でも結果は同じになります。ファイルを開いて確認すると、次のようになります。
Hello! Добро пожаловать на JavaRush — лучший сайт для тех, кто хочет стать программистом!
ただし、ここで注意点が 1 つあります。上記の例のコードを連続して数回実行してみて、ファイルを見て、ファイルに何行書かれているかという質問に答えてください。一つだけ。しかし、コードを数回実行しました。しかし、そのたびにデータが上書きされ、古いデータが置き換えられていたことが判明しました。これに満足できず、連続記録が必要な場合はどうすればよいでしょうか? ファイルに挨拶を 3 回続けて書き込みたい場合はどうすればよいでしょうか? ここではすべてがシンプルです。言語自体はそれぞれの場合にどのような動作が必要かを知ることができないため、FileOutputStream
追加のパラメーターをコンストラクターに渡すことができます - boolean append
。その値がtrueの場合、データはファイルの最後に書き込まれます。falseの場合(デフォルト値はfalse )、古いデータが消去され、新しいデータが書き込まれます。変更したコードを 3 回テストして実行してみましょう。
public class Main {
public static void main(String[] args) throws IOException {
FileOutputStream fileOutputStream = new FileOutputStream("C:\\Users\\Username\\Desktop\\test.txt", true);
String greetings = "Hi! Welcome to JavaRush - the best site for those who want to become a programmer!\r\n";
fileOutputStream.write(greetings.getBytes());
fileOutputStream.close();
}
}
ファイル内の結果:
Hello! Добро пожаловать на JavaRush - лучший сайт для тех, кто хочет стать программистом!
Hello! Добро пожаловать на JavaRush - лучший сайт для тех, кто хочет стать программистом!
Hello! Добро пожаловать на JavaRush - лучший сайт для тех, кто хочет стать программистом!
別物!I/O クラスを使用するときは、この機能に留意してください。かつては、古いデータがファイルのどこにあるのかを理解するために、何時間もタスクに取り組み続けなければなりませんでした :) そしてもちろん、他の I/O クラスの場合と同様に、 を通じてリソースを解放することを忘れないでくださいclose()
。
FileInputStream クラス
このクラスには、FileInputStream
ファイルからバイトを読み取るという逆の目的があります。FileOutputStream
継承と同様にOutputStream
、このクラスは抽象クラスから派生しますInputStream
。テキスト「test.txt 」に数行のテキストを 書き込んでみましょう。
«So close no matter how far
Couldn't be much more from the heart
Forever trusting who we are
And nothing else matters»
これは、次を使用してファイルからデータを読み取る実装ですFileInputStream
。
public class Main {
public static void main(String[] args) throws IOException {
FileInputStream fileInputStream = new FileInputStream("C:\\Users\\Username\\Desktop\\test.txt");
int i;
while((i=fileInputStream.read())!= -1){
System.out.print((char)i);
}
}
}
ファイルから 1 バイトを読み取り、読み取ったバイトを文字に変換してコンソールに出力します。そして、コンソールの結果は次のとおりです。
So close no matter how far
Couldn't be much more from the heart
Forever trusting who we are
And nothing else matters
BufferedInputStream クラス
これまでの講義の知識があれば、このクラスが必要な理由BufferedInputStream
と、このクラスに比べてどのような利点があるのかが簡単にFileInputStream
わかると思います :) すでにバッファリングされたストリームについて説明しましたので、読み続ける前に推測 (または思い出してください) してください :) バッファリングされたストリーム主に I/O を最適化するために必要です。 ファイルからの読み取りなど、データ ソースへのアクセスは、パフォーマンスを重視する操作です。また、毎回ファイルにアクセスして 1 バイト読み取るのは無駄です。したがって、BufferedInputStream
一度に 1 バイトずつではなく、ブロック単位でデータを読み取り、特別なバッファーに一時的に保存します。これにより、ファイルへのアクセス数が減り、プログラムの動作が最適化されます。どのようなものかを見てみましょう:
public class Main {
public static void main(String[] args) throws IOException {
FileInputStream fileInputStream = new FileInputStream("C:\\Users\\Username\\Desktop\\test.txt");
BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream, 200);
int i;
while((i = bufferedInputStream.read())!= -1){
System.out.print((char)i);
}
}
}
ここではオブジェクトを作成しましたBufferedInputStream
。これはオブジェクトまたはその後継オブジェクトを input として受け入れるInputStream
ため、前のオブジェクトでFileInputStream
十分です。追加パラメータとしてバッファ サイズをバイト単位で受け取ります。これにより、ファイルからデータが一度に 1 バイトずつではなく、一度に 200 バイトずつ読み取られるようになりました。ファイル アクセスの数がどれだけ削減されたかを想像してみてください。FileInputStream
パフォーマンスを比較するには、数メガバイトの大きなテキスト ファイルを取得し、と を使用して、それを読み取ってコンソールに出力するのにかかる時間をミリ秒単位で比較しますBufferedInputStream
。両方のコード例を次に示します。
public class Main {
public static void main(String[] args) throws IOException {
Date date = new Date();
FileInputStream fileInputStream = new FileInputStream("C:\\Users\\Username\\Desktop\\textBook.rtf");
BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream);
int i;
while((i = bufferedInputStream.read())!= -1){
System.out.print((char)i);
}
Date date1 = new Date();
System.out.println((date1.getTime() - date.getTime()));
}
}
public class Main {
public static void main(String[] args) throws IOException {
Date date = new Date();
FileInputStream fileInputStream = new FileInputStream("C:\\Users\\Username\\Desktop\\26951280.rtf");
int i;
while((i = fileInputStream.read())!= -1){
System.out.print((char)i);
}
Date date1 = new Date();
System.out.println((date1.getTime() - date.getTime()));
}
}
私のコンピューターで 1.5 MB のファイルを読み取る場合、FileInputStream
ジョブは約 3500 ミリ秒で完了しましたが、ここでBufferedInputStream
は約 1700 ミリ秒で完了しました。ご覧のとおり、バッファリングされたストリームにより、プログラムのパフォーマンスが 2 倍最適化されました。:) 私たちは I/O クラスの研究を続けます - すぐにお会いしましょう!
GO TO FULL VERSION