JAVAの基本-IOストリーム(1)バイトストリーム、4つのコピーモード、バイトストリームコピー画像、mp3モード

1.概念と分類

  1. コンセプト
    IOストリームは、デバイス間のデータ送信を処理するために使用されます
    • データに対するJavaの操作は、ストリーミングを介して行われます。
    • Javaがストリームを操作するために使用するクラスはすべてIOパッケージに含まれています
    • 流れは、流れの方向によって、入力フローと出力フローの2種類に分けられます。
    • ストリームは、操作タイプに応じて2つのタイプに分けられます。
      • バイトストリーム :コンピュータ内のデータはバイト形式で保存されるため、バイトストリームは任意のデータを操作できます
      • キャラクターストリーム:文字ストリームは純粋な文字データでのみ動作できるため、より便利です。
        次の章では、IOストリームのバイトストリームと文字ストリームを紹介します
  2. IOストリームの共通の親クラス
  • バイトストリームの抽象親クラス:
    InputStream
    OutputStream
  • 文字ストリームの抽象的な親クラス:
    読者
    作家
  1. 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メソッドを作成する場合は、このインターフェイスを使用する必要があります

おすすめ

転載: blog.csdn.net/Mr_GYF/article/details/108805017