IOパックの流れ

14540 ワード

IO(Input Output)フロー
  • IOストリームは、デバイス間のデータ伝送を処理するために使用される
  • .
  • Javaによるデータの操作時にストリームを通過する方式
  • Javaストリームを操作するオブジェクトは、IOパッケージの
  • にあります.
  • ストリームは、操作データによって2つに分けられる:バイトストリームと文字ストリーム
  • ストリームはタイプ別に入力ストリーム、出力ストリーム
  • に分けられる.
    IOフロー共通ベースクラス
  • バイトストリームの抽象ベースクラスオブジェクト:InputStream,OutputStream
  • 文字ストリームの抽象ベースクラスオブジェクト:Reader,Writer注:この4つのクラスから派生したサブクラス名は、いずれもその親の名作からサブクラス名の接尾辞である.例:InputStreamのサブクラスFileInputStream例:ReaderのサブクラスFileReader
  • 完全なストリームファミリー
    入力ストリームと出力ストリームの階層
    ReaderとWriterの階層
    FileReaderおよびFileWriterストリーム
    //指定ディレクトリの下にファイルが作成されるFileWriterオブジェクトを作成します.同じ名前の場合、構築方法の2番目のパラメータappendがtrueでない限り、上書きされます.
        /**
         * 
         * @param  str
         *         String to be written
         *         
         * @throws IOException
         */
        public static void createFile(String str) throws IOException{
            // D    abc.txt.        ,           append true;        
            File file = new File("D:" + File.separator + "abc.txt");        
            FileWriter fw = new FileWriter(file, false);             
            fw.write(str);                      
            fw.flush(); //     ,   flash        .      
            fw.close(); // flush   : flush          ,close     ,            
        }   
    

    IO異常の標準処理方式一(FileWriterを例に)
            String fileName = "D:" + File.separatorChar + "abc.txt";
            
            FileWriter fw = null;       
            try {
                fw = new FileWriter(fileName);
                fw.write("balabala...");
                fw.flush();
            } catch (IOException e) {
                //           
                throw new RuntimeException("  IO  ");
            } finally {
                if (fw != null)
                    try {
                        fw.close();
                    } catch (IOException e) {
                        throw new RuntimeException("     ");
                    }
            }
    

    IO異常の標準処理方式2(SE 7 try-with-resources方式)
            String fileName = "D:" + File.separatorChar + "abc.txt";
    
            try (FileWriter fw = new FileWriter(fileName)) {
                fw.write("balabala...");
                fw.flush();
            } catch (IOException e) {
                //           
                throw new RuntimeException("  IO  ");
            }
    

    FileReaderを使用してテキストファイルを読み込む方法1
         int ch = 0;
         while((ch=fr.read())!=-1){
              //relevant operation
         }
    

    FileReaderを使用してテキストファイルを読み込む方法2(方法1より、推奨)
     int len= 0;
         char[] buf = new char[1024];
         while((len=fr.read(buf))!=-1){
              //relevant operation
         }
    

    ファイルのコピー(使用方法2)/relevant operation-->fileWriter.write(buf,0,len);
    文字ストリームのバッファフローBufferedReaderとBufferedWriter
  • データの読み書き効率が向上
  • 対応クラス:BufferedReaderおよびBufferedWriter
  • バッファは、ストリームと結合するために
  • を使用することができる.
  • 流に基づいて対流する機能を増強した
  • **BufferedWriter **
  • は、文字書き込みストリームの効率を向上するために、効率を向上する必要があるストリームオブジェクトをパラメータとしてBufferedWriterに渡す構成方法である.
  • BufferedWriterには独自のreadLine()メソッドがあります.これは、行の終端を含まない
  • です.
  • 改行が必要な場合bfr.新Line()そしてflush()最後にcloseストリームを忘れないでください.//私の理解では、BufferedWriterとBufferedReaderはいずれも元のストリームに基づいており、元のストリームに関心を持っている.各行の書き込みと読み取りが提供され、余分な行終端子を含まない.だから自分で改行するたびに.

  • BufferedReaderデータの読み込み
            String line = null;
            while((line=bfr.readLine())!=null){
                //relevant operation
            }
    

    BufferedWriterを使用して、BufferedReaderはファイルキーコードをコピーします.
             String line = null;
             while((line=bfr.readLine())!=null){
                  bfr.write(line);
                  bfr.newLine();
                  bfr.flush();
             }
    

    装飾デザインにかかわる
  • 既存のオブジェクトの機能強化を先に行う場合、クラスを定義し、既存のオブジェクトを転送し、既存の機能に基づいて強化機能を提供することができる.
  • の装飾類は、通常、構造方法によって装飾するオブジェクトを受け取り、装飾するオブジェクトの機能に基づいてより強い機能を提供する.
  • 装飾モードは継承より柔軟で、継承システムの肥大化を避けた.またクラスとクラスとの関係を低減する、装飾類は既存のオブジェクトを強化するため、備える機能は既存のものと同じであり、より強い機能を提供するにすぎない.従って、装飾類と比装飾類は、通常、一つの体系に属する.

  • LineNumberReader BufferedReader()のサブクラスは、ラベルが増えただけです.setLineNumberで初期行番号を設定し、出力でgetLineNumberで各行の行番号を取得できます.
    バイトストリームFileOutputStreamとFileInputStream
    画像、音楽などのファイルの読み書きをバイナリ形式で行うことができる.
         //      
         public static void copyFile() throws IOException{
              InputStream fis = new FileInputStream("D:\\source.jpg" );
              OutputStream fos = new FileOutputStream("D:\\dst.jpg" );
               int len = 0;
               byte[] buf = new byte[1024];
               while((len=fis.read(buf))!=-1){
                  fos.write(buf, 0, len);
              }
              fis.close();       
    

    歌をコピー(バイトストリームのBufferedバッファを使用)
    InputStream inputStream = new BufferedInputStream(
              new FileInputStream("D:" + File.separator + "   -     .mp3"));        
    OutputStream outputStream = new BufferedOutputStream(
              new FileOutputStream("D:" + File.separator + "   -     .mp3"));       
    

    キーボード入力(InputStreamReaderとOutputStreamWriter変換ストリーム)
    System.out:標準入力装置、コンソールSystemに対応する.in:標準出力装置、キーボードに対応
    練習:キーボードで入力し、1行のデータを入力と改行データを印刷し、入力データがoverであれば入力を停止する.
    //   :     
    //           :  ASCII  13 '\r', 10 '
    ' public static void method1() throws IOException{ final InputStream in = System.in; int character ; final StringBuilder stringBuilder = new StringBuilder(); while(true){ character = in.read(); switch (character) { case '\r': break; case '
    ': final String result = stringBuilder.toString(); if("over".equals(result)){ return; } //StringBuilder stringBuilder.delete(0, stringBuilder.length()); break; default: stringBuilder.append((char)character); break; } } } // : InputStreamReader , , public static void method2() throws IOException{ final InputStream in = System.in; final BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(in)); String line = null; while ((line = bufferedReader.readLine()) != null) { if("over".equals(line)){ break; } } } // : Scanner [5.0] public static void method3(String[] args) throws IOException { final InputStream in = System.in; String line = null; final Scanner scanner = new Scanner(in); while(scanner.hasNextLine()){ line = scanner.nextLine(); if("over".equals(line)){ break; } } }

    OutputStreamWriter変換フロー
    InputStreamReaderと同様に、文字がバイトストリームに流れる橋渡しである.包装だけだバッファリング後
    OutputStream os = System.out;       
    OutputStreamWriter outputStreamWriter = new OutputStreamWriter(os); 
    outputStreamWriter.write("cba");    
    outputStreamWriter.flush();     
    outputStreamWriter.close();
    

    フロー操作法則
  • 明確なソースと目的
  • が純粋なテキスト(バイトストリームと文字ストリームの選択)であるかどうか、具体的にどのオブジェクト
  • を使用するか
  • は、効率を向上するためにバッファを加える必要があるか否かに関するOutputStream(OutputStream out,String charsetName)は、文字のバイト変換の橋渡しであり、カスタム符号化、例えば「UTF-8」を指定することができ、これも変換ストリームが発生する原因である.

  • 標準入出力装置の変更
    SystemのsetIn()メソッドは、標準入力ストリームを再割り当てします.標準入力ストリームは通常キーボードInputStreamである.SystemのsetOut()メソッドは、「標準」出力ストリームを再割り当てします.標準入力ストリームは通常キーボードPrintStreamである.この2つの関連付けられたストリームを使用して関連操作を行うことができます.
    印刷ストリームPrintStreamとPrintWriter
    このストリームは、各種のデータをそのまま印刷することができる印刷方法を提供する.
    PrintStream PrintStreamは、他の出力ストリームに機能を追加し、各種データ値表示形式を容易に印刷できるようにした.他にも2つの機能があります.他の出力ストリームとは異なり、PrintStreamはIOExceptionを放出しません.代わりに、例外はcheckErrorメソッドでテストできる内部フラグのみを設定します.また、自動的にリフレッシュするためにPrintStreamを作成できます.これは、byte配列の書き込み後にflushメソッドを自動的に呼び出すことができ、printlnメソッドの1つを呼び出すことができ、改行またはバイト(')を書き込むことができることを意味します.
    PrintStream印刷のすべての文字は、プラットフォームのデフォルト文字符号化を使用してバイトに変換されます.バイトではなく文字を書き込む必要がある場合は、PrintWriterクラスを使用します.
    PrintWriter
  • 文字出力ストリームWriter
  • を追加
            //       
            PrintWriter pw = new PrintWriter(System.out, true);
            String line = null;
            BufferedReader bfr = new BufferedReader(new InputStreamReader(System.in));
            while ((line = bfr.readLine()) != null) {
                //      BufferedWriter   .PrintWriter         .
                pw.println(line);
            }
    

    シーケンスストリームSequenceInputStream(**は他の入力ストリームの論理直列を表し、対応する出力ストリームがない)
    練習:ファイルの分割とマージ
         //       ,      
         public static void split() throws IOException{
              FileInputStream fis = new FileInputStream("d:\\123.pdf" );
              FileOutputStream fos = null;
               int len = 0;
               //1M=1024KB=1024*1024     
               byte[] buf = new byte[1024*1024];
               int i=0;
               while((len=fis.read(buf))!=-1){
                  fos = new FileOutputStream("d:\\" +(++i)+ ".part");
                  fos.write(buf, 0, len);
                  fos.flush();
                  fos.close();;
              }
              fis.close();       
         }
         //    
         public static void meger() throws IOException{
              Vector v = new Vector ();
               for(int i=1;i<4;i++)
                  v.add( new FileInputStream("d:\\" + i+".part"));
              SequenceInputStream sis = new SequenceInputStream(v.elements());
              FileOutputStream fos = new FileOutputStream("d:\\kk.pdf" );       
               int len = 0;
               byte[] buf = new byte[1024];
               while((len=sis.read(buf))!=-1){
                  fos.write(buf, 0, len);
              }
              sis.close();
              fos.close();
         }
    

    操作オブジェクトのObjectInputStreamとObjectOutputStream
  • が操作するオブジェクトは、Serializable(タグインタフェース)
  • を実現する必要がある.
  • シーケンス化可能クラスは、「serialVersionUID」というフィールド(このフィールドは静的(static)、最終(final)のlong型フィールドである必要がある)を宣言することによって、独自のserialVersionUID ANY-ACCES-MODIFIER static final long serialVersionUID=42 Lを明示的に宣言することができる.このようにして生成する新しいクラスは、システムによって生成されたUIDではなく、UIDを変更することはない.
  • その他の非静的メンバー変数はtransient修飾が直列化されず、同様のクラス変数も直列化されない.

  • 16.パイプフローPipedInputStramとPipedOutputStream
  • 入出力は直接接続可能であり、結合スレッドは
  • を用いる.
    PipedInputStreamは、別の出力パイプに接続するためにInputStreamオブジェクトを受信し、出力パイプに書き込まれたデータを読み出し、プログラム内のスレッドの通信に使用します.
    PipedOutputStreamでは、パイプ出力ストリームをパイプ入力ストリームに接続して通信パイプを作成できます.パイプ出力ストリームはパイプの送信端です.通常、データはあるスレッドによってPipedOutputStreamオブジェクトに書き込まれ、他のスレッドによって接続されたPipedInputStreamから読み出されます.
    public class DemoPipedStream {
     
        public static void main(String[] args) throws IOException {
            //       
            PipedInputStream pis = new PipedInputStream();
            //              ,     connect
            PipedOutputStream pos = new PipedOutputStream(pis);
            new Thread(new Write(pos)).start();
            new Thread(new Read(pis)).start();       
        }
    }
     
    class Read implements Runnable{
        private PipedInputStream pis;
        public Read(PipedInputStream pis){
            this.pis = pis;
        }
        @Override
        public void run(){   
            byte[] buf = new byte[200];
            try{
                System.out.println("---         ");
                int len = pis.read(buf);
                System.out.println("--"+new String(buf,0,len));
                System.out.println("---          ");
            }catch(IOException e){
                throw new RuntimeException("     ");
            }
            finally{
                if(pis!=null)
                    try{pis.close();}
                catch(IOException e){
                    throw new RuntimeException("     ");
                }
            }
        }  
    }
     
    class Write implements Runnable{
        private PipedOutputStream pos;
        public Write(PipedOutputStream pos){
            this.pos = pos;
        }
        public void run(){
            try {
                System.out.println("          ,  3S");
                try {
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                pos.write("Hello PipedStram".getBytes());
                System.out.println("         ");
            } catch (IOException e) {          
                throw new RuntimeException("     ");
            }
            finally{
                if(pos!=null)
                    try{pos.close();}
                catch(IOException e){
                    throw new RuntimeException("     ");
                }
            }
        }
    }
    

    RandomAccessFile
    ファイル内の任意の場所でデータを検索または書き込むことができます.ディスク・ファイルはランダムにアクセスされますが、ネットワークからのデータ・ストリームはそうではありません.読み込み専用または読み書き用のランダムアクセスファイルを開くことができます.コンストラクタの2番目のパラメータは、このオプションを指定します.
  • 「r」は読み取り専用モードを表す.
  • 「rw」は読み書きモードを表す.
  • 「rws」は、更新のたびにデータとメタデータの書き込みディスク操作を同期させる読み取り/書き込みモードを表す.
  • 「rwd」は、更新毎に、データの書き込みディスク操作のみを同期する読み取り/書き込みモード
  • を表す.
         //       
         seek(long pos)
         //        n            。
         skipBytes()
    

    基本データ型の操作
    基本JavaタイプDataInputStreamとDataOutputstreamのバイト配列ByteArrayInputStreamとByteArrayOutputStreamの操作文字配列CharArrayReaderとCharArrayWriterの操作文字列StringReaderとStringWriter
    まとめ:データをバイナリ形式で書き出し、DataOutputStreamを使用する必要があります.データをテキスト形式で書くには、PrintWriterを使用する必要があります.
    PrintWriter printWriter = new PrintWriter("setting.dat", "UTF-8");
    

    文字セット
    過去には国際化文字セットが処理されていたが,処理は系統的ではなくJavaクラスライブラリのあちこちに散在していた.Java SE 1.4に導入するjava.NioパッケージはCharsetクラスで文字セットへの変換を統一している(sは小文字であることに注意).
            //  Charset  
            Charset.defaultCharset(); //            
            Charset charset = Charset.forName("UTF-8");//             
        
            //Returns a set containing this charset's aliases.
            for(String alias: charset.aliases()){
                System.out.println(alias);
            }
            
            //  Java   
            ByteBuffer bytBuffer = charset.encode("       ,        ");
            byte[] bytes = bytBuffer.array();
            
            //        ,        
            CharBuffer cbuf = charset.decode(bytBuffer);
            System.out.println(cbuf.toString());    
    

    文字コード
    //「こんにちは」-->「?」GBK変utf-8です;-->「浣
    練習:5人の学生がいて、各学生は3人の授業があって、キーボードの入力(名前を含んで、3つの授業の成績.)出力フォーマット:張三、39、76、54のように総成績を計算し、学生情報と総点数がstudに高くなるまで同時に保存する.txt.