1.概念と分類
- コンセプト
IOストリームは、デバイス間のデータ送信を処理するために使用されます- データに対するJavaの操作は、ストリーミングを介して行われます。
- Javaがストリームを操作するために使用するクラスはすべてIOパッケージに含まれています
- 流れは、流れの方向によって、入力フローと出力フローの2種類に分けられます。
- ストリームは、操作タイプに応じて2つのタイプに分けられます。
- バイトストリーム :コンピュータ内のデータはバイト形式で保存されるため、バイトストリームは任意のデータを操作できます
- キャラクターストリーム:文字ストリームは純粋な文字データでのみ動作できるため、より便利です。
次の章では、IOストリームのバイトストリームと文字ストリームを紹介します
- IOストリームの共通の親クラス
- バイトストリームの抽象親クラス:
InputStream
OutputStream - 文字ストリームの抽象的な親クラス:
読者
作家
- IOプログラムの作成
- 使用する前に、IOパッケージのクラスをインポートしてください
- 使用中は、IO例外処理を実行してください
- 使用後、リソースを解放します。
以下を十分に理解する必要があります。ユーザーの観点からではなく、メモリに関連して入力と出力が行われます。つまり、FileInputStreamが入力を実行します。私たちが書いた文書から要素を取得するのは記憶です。独自のバッファに入力します。つまり、読み取る必要があります。そして、javaバッファーから何かを出力する、つまり、OutputStreamを実行し、バッファーから必要なものを書き込みます。
次の章では、バイトストリームを紹介します
2、FileInputStream(入力用)
InputStreamは抽象クラスであるため、それ自体でオブジェクトを生成することはできません。したがって、最初のサブクラスFileInputStreamを学習します。
FileInputSteamのread()メソッドで、最初にこのプロジェクトの下に新しいtxtファイルを作成し、XXX.txtという名前を付ける必要があります。その中に3文字のabcを書く
ケース:
FileInputStream fileInputStream =new FileInputStream("xxx.txt");
int x =fileInputStream.read(); //创建流对象
System.out.println(x); //从硬盘上读取一个字节
int y =fileInputStream.read();
System.out.println(y);
int z =fileInputStream.read();
System.out.println(z);
int b =fileInputStream.read();
System.out.println(b);
fileInputStream.close(); //关闭释放资源
その効果は次のとおりです
。readメソッドを実行するたびに、文字に対応するコードテーブルに対応する番号のみが出力されることがわかりました。しかし、最後の数値を読んで、戻り値が-1であることがわかったとき。最適化できる
FileInputStream fileInputStream =new FileInputStream("xxx.txt");
int b;
while ((b=fileInputStream.read())!=-1) {
System.out.println(b);
}
fileInputStream.close();
3. read()メソッドの戻り値がintである理由
read()メソッドはバイトを読み取ります。なぜバイトではなくintが返されるのですか?
バイト入力ストリームは画像やオーディオなどの任意のタイプのファイルで動作できるため、これらのファイルは最下層にバイナリ形式で保存されます。バイトは1バイトを占め、1バイトは8つのバイナリ番号で構成されているため、各読み取りはバイトを返します。真ん中を読み取るときに111111111(-1の補数)に遭遇する可能性
があります。この11111111はバイトタイプ-1であり、-1に遭遇するとプログラムは読み取りを停止し、次のデータは読み取られません。読み取るときに、intタイプを使用して受信します。11111111がその前に24個の0を追加して4バイトを構成する場合、バイトタイプ-1はintタイプ255(00000000 00000000 00000000 11111111)になります。これは保証できます。データ全体が読み取られ、終了タグ-1(-1に等しいものを転送する必要はありません)はint型です。
4、FileOutputStream(出力用)
FileOutputStream fileOutputStream =new FileOutputStream("yyy.txt");
fileOutputStream.write(97);
//虽然写出的是一个int数。但是到文件上的是一个字节 会自动去除前三个8位
fileOutputStream.write(98);
fileOutputStream.write(99);
fileOutputStream.close();
この時点で、プロジェクトパスの下に新しいyyy.txtが表示されます。そして、いくつかのコンテンツを書いた、
効果は次のとおりです:
五、 FileOutputStream追加
以前に書かれたコンテンツに注釈を付けると、後で書かれたコンテンツが変更されることがわかります。
出力したい場合は、abcd。追加する必要があることを示します。ファイルの内容は変更されません。
FileOutputStream fileOutputStream =new FileOutputStream("yyy.txt",true);
fileOutputStream.write(97);
//虽然写出的是一个int数。但是到文件上的是一个字节 会自动去除前三个8位
fileOutputStream.write(98);
fileOutputStream.write(99);
fileOutputStream.write(100);
fileOutputStream.close();
効果は次のとおりです。
この機能の適用シナリオでは、チャットレコードを検索するときにチャットレコードのコンテンツを追加できます。
6、写真をコピーする(最初のコピー方法)
まず、写真が必要で、その写真をプロジェクトの下に置きます。変更ラインコードは、IOストリームの主流コードです。mp3をコピーする場合は、括弧内の値を変更するだけで済みます。しかし、効率が遅すぎるため、バイトごとに読み取る必要があります。
FileInputStream fileInputStream =new FileInputStream("6.jpg");//创建输入流对象
FileOutputStream fileOutputStream =new FileOutputStream("copy.jpg");//创建输出流对象
int b;
while((b=fileInputStream.read())!=-1) {
//在不断地读取每一个字节
fileOutputStream.write(b);
//将每一个字节写出
}
fileOutputStream.close();
fileInputStream.close();
このとき、写真をコピーします。しかし、効率が遅すぎるため、バイトごとに読み取る必要があります。
そこで、ファイル全体を読み取る方法を紹介します。つまり、available()メソッド
7.バイト配列コピーのAvailable()メソッド(2番目のコピーメソッド)
FileInputStream fileInputStream =new FileInputStream("6.jpg");
FileOutputStream fileOutputStream =new FileOutputStream("copy.jpg");
int len =fileInputStream.available();
System.out.println(len);
fileInputStream.close();
fileOutputStream.close();
効果は次のとおりです
。数値は、ファイルが占めるバイト値、バイトです。
だから、私たちはアップグレードすることができます。
FileInputStream fileInputStream =new FileInputStream("6.jpg");
FileOutputStream fileOutputStream =new FileOutputStream("copy.jpg");
byte[] arr=new byte[fileInputStream.available()];
//创建与文件一样大小的字节数组
fileInputStream.read(arr);
//将文件上的字节读取到内存中
fileOutputStream.write(arr);
//将字节数组中的字节数据写到文件上
fileInputStream.close();
fileOutputStream.close();
効果は次のとおりです
。開発中、このメソッド配列を使用してファイルをコピーすることはお勧めしません。ファイルが大きすぎると、メモリオーバーフローが発生する可能性があります。
8.グループの数を定義します(3番目のコピー方法)
FileInputStream fileInputStream =new FileInputStream("xxx.txt");
byte[] arr=new byte[2];
int a =fileInputStream.read(arr);
System.out.println(a);
for (byte b : arr) {
System.out.println(b);
}
System.out.println("--------------");
int c=fileInputStream.read(arr);
System.out.println(c);
for (byte b : arr) {
System.out.println(b);
}
fileInputStream.close();
効果は次のとおりです。
現時点では、2つの数値しか読み取れないことがわかりました。初めて読むときはab(97 98)を限られた量だけ読みますが、もう一度2つの数字を読むときは、cがaの位置を占めるので、9999が読みます。
したがって、読み取りと書き込みを行うときは、次の操作を実行します
FileInputStream fileInputStream =new FileInputStream("xxx.txt");
FileOutputStream fileOutputStream =new FileOutputStream("yyy.txt");
byte []arr =new byte[2];
int len;
while((len=fileInputStream.read(arr))!=-1) {
fileOutputStream.write(arr, 0, len);
}
fileInputStream.close();
fileOutputStream.close();
効果は次のとおりです。
標準の書き込み方法:通常、データを2つずつ読み取るのではなく、1024の倍数で読む、
したがって、アップグレードするには:
FileInputStream fileInputStream =new FileInputStream("xxx.txt");
FileOutputStream fileOutputStream =new FileOutputStream("yyy.txt");
byte[] arr=new byte[1024*8];
int len;
while((len=fileInputStream.read(arr))!=-1) {
//如果忘记加arr,返回的就不是读取的字节个数,而是字节的码表值
fileOutputStream.write(b, 0, len);
}
効果は同じですが、効率は2倍になります。
9、BufferedInputStreamおよびBufferOutputStreamコピー(4番目のコピー方法)
バッファー思考
- 一度に配列を読み書きするバイトストリームの速度は、一度に1バイトを読み書きするよりも明らかにはるかに高速です。
- これは、配列などのバッファ効果の追加です。Java自体が設計されたとき、
- この設計アイデアも考慮されるため(装飾設計パターンの後半で説明)、バイトバッファストリームが提供されます。
BufferedInputStream
- BufferedInputStreamには、組み込みのバッファー(配列)があります。
- BufferedInputStreamからバイトを読み取る場合
- BufferedInputStreamは、ファイルから8192を一度に読み取り、それらをバッファーに格納して、プログラムに返します。
- プログラムが再度読み取る場合、ファイルを見つける必要はありません。ファイルはバッファーから直接取得されます。
- すべてのバッファーが使用されるまで、8192がファイルから再度読み取られます
BufferedOutputStream
BufferedOutputStreamには、組み込みのバッファー(配列)もあります。
- プログラムがストリームにバイトを書き込むとき、ファイルに直接書き込むのではなく、最初にバッファに書き込みます。
- バッファがいっぱいになるまで、BufferedOutputStreamはバッファ内のデータを一度にファイルに書き込みます。
FileInputStream fileInputStream =new FileInputStream("6.jpg");
//创建输入流对象6.jpg
FileOutputStream fileOutputStream =
new FileOutputStream("copy.jpg");
//创建输出流对象copy.jpg
BufferedInputStream bufferedInputStream =
new BufferedInputStream(fileInputStream);
//创建缓冲区对象,对输入流进行包装让其更加强大
BufferedOutputStream bufferedOutputStream =new BufferedOutputStream(fileOutputStream);
//创建缓冲区对象,对输出流进行包装让其更加强大
int b;
while ((b=bufferedInputStream.read())!=-1) {
bufferedOutputStream.write(b);
}
bufferedInputStream.close();
bufferedOutputStream.close();
- 小さな配列の読み取りと書き込み、またはBufferedでの読み取りのどちらが高速ですか?
- 8192バイトのサイズをBufferedと比較する場合は、小さな配列を定義します
- 読み取り操作と書き込み操作は同じ配列であるため、小さな配列を定義することをお勧めします。
- そしてBufferedは2つのアレイで動作します
10、フラッシュとクローズの方法の違い
flush()メソッド
- バッファを更新するために使用され、更新後に再度書き出すことができます
close()メソッド
- ストリームを閉じてリソースを解放するために使用されます。これがバッファ付きのストリームオブジェクトのclose()メソッドである場合、ストリームを閉じるだけでなく、ストリームを閉じる前にバッファをフラッシュし、閉じた後に書き出すことはできません。
- 簡単に言えば、リフレッシュ機能があり、閉じる前に再度バッファをリフレッシュします。バッファに8192バイト余分にある場合は500バイトになる場合があります。最後にバッファをリフレッシュします。ファイル内のすべてのバイトを更新してから閉じます
11.中国語の読み取りと書き込みのバイトストリーム
バイトストリームで中国語を読み取る問題:バイトストリームで中国語を読み取ると、中国語の半分を読み取ることができ、文字化けした
バイトストリームで中国語を書き込むことができます。バイトストリームはバイトを直接操作するため、中国語で文字列はバイト出力に変換する必要があります。キャリッジリターンとラインフィードを記述します。write( "\ r \ n" .getBytes())
FileInputStream fileInputStream =new FileInputStream("yyy.txt");
byte [] arr=new byte[3];
int len;
while ((len=fileInputStream.read(arr))!=-1) {
System.out.println(new String(arr,0,len));
}
fileInputStream.close();
効果は次のとおりです。
中国語の単語は2バイトであり、読み取る配列の長さは3バイトであるため、単語は半分に分割されて読み取られ、認識に失敗します。
FileOutputStream fileOutputStream =new FileOutputStream("yyy.txt");
fileOutputStream.write("我在学习字节流".getBytes()); //把字节数组写出去
fileOutputStream.close();
効果は次のとおりです。
書かれた中国語を直接配列に格納するため、問題はありません。
12、try-catch-最終的にIOストリームの表現
jdk1.6以降:
public static void demo1() throws FileNotFoundException, IOException {
FileInputStream fileInputStream =null;
FileOutputStream fileOutputStream =null;
int b;
try {
fileInputStream =new FileInputStream("xxx.txt");
fileOutputStream =new FileOutputStream("yyy.txt");
while ((b=fileInputStream.read())!=-1) {
fileOutputStream.write(b);
}
}finally {
try {
if (fileInputStream!=null)
fileInputStream.close();
}finally {
if (fileOutputStream!=null) {
fileOutputStream.close();
}
}
}
}
jdk1.7バージョン以降
try(
FileInputStream fileInputStream = new FileInputStream("xxx.txt");
FileOutputStream fileOutputStream =new FileOutputStream("yyy.txt");
){
int b;
while ((b=fileInputStream.read())!=-1) {
fileOutputStream.write(b);
}
}
jdk1.7バージョンでは、最初に括弧()を使用して、入力および出力ストリーム操作を実行してみてください彼らが呼ぶので自動クローズ可能インターフェース。入力ストリームと出力ストリームを自動的に閉じます。自分でcloseメソッドを作成する場合は、このインターフェイスを使用する必要があります