Java-IO 輸入輸出流詳解

1、文件的編碼java

              開發時必定要注意項目默認的編碼!!!!!!!!
              文件操做的時候必定要記得關閉!!!!!!!!
       ASCII:美國標準信息交換碼,用一個字節的7位能夠表示一個字符
       ISO8859-1:拉丁碼錶,西歐標準字符集,用一個字節的8位表示
       GB2312:中文編碼表,用兩個字節來表示中文編碼
       GBK:中文編碼表的升級,融合了更多表示中文文字符號
       GB18030:GBK的取代版本
       BIG-5:同行與港臺地區,是繁體字編碼方案,俗稱「大五碼」
       Uicode:國際標準碼,融合了多種文字
       UTF-8:是Unicode編碼的實現方式,最多用三個字節來表示一個字符
    
       GBK編碼     中文佔用2個字節,英文佔用1個字節
       UTF-8編碼   中文佔用3個字節,英文佔用1個字節
       UTF-16be編碼中文佔用2個字節,英文佔用2個字節
       Java是雙字節編碼 utf-16be,即java中每一個字符佔用兩個字節
       
       當你想把一個字節序列變成一個字符串時,字節序列使用什麼編碼,就須要使用什麼編碼去顯示的調用s.getBytes("字節序列的編碼格式");,不然會出現亂碼
 
       文本文件就是字節序列,能夠是任意編碼的字節序列,可是若是是在中文機器上直接建立文本文件,那麼該文本文件只認識ANSI(本地編碼)編碼。如,新建一個TXT文件,內容爲聯通,打開則會出現亂碼,是一種巧合,正好符合了UTF-8編碼的規則
   
       Integer.toHexString(Byte);//以十六進制的方式顯示
2、File工具類的使用
         一、File類用於表示文件和目錄均可以
            File類只用於表示文件(目錄)的信息(名稱、大小等),不能用於文件內容的訪問
         二、File類的基本API(看手冊)
                 構造函數的狀況
                建立功能:createNewFile(),mkdir(),mkdirs()
                刪除功能:delete()
                重命名功能:renameTo()
                判斷功能:isFile(),isDirectory(),exists()等
                獲取功能:getName(),getPath(),list()等
                文件過濾器的做用:list(FilenameFilter filter),返回知足指定條件的文件列表
                
            判斷參數的時候,可使用 IllegalArgumentException參數拋出異常
            File.separator設置目錄分隔符,Windows、Unix都識別
            相對目錄是當前目錄,也即在項目的根目錄下
         三、遍歷目錄(遞歸 dir.listFiles())
            訪問文件系統的時候由於是與JVM之外的資源進行交互,因此,寫代碼必定要嚴謹,把各類狀況考慮到了
             
3、RandomAccessFile類的使用
       一、 RandomAccessFile  java提供的對文件內容的訪問,既能夠讀,也能夠寫
          且支持隨機訪問文件,能夠訪問文件的任意位置
       二、Java文件模型
             在硬盤上的文件是byte byte byte存儲的,是數據的集合
       三、打開文件  
1 RandomAccessFile raf =newRandomAccessFile(file,"rw");//rw,讀寫,r只讀
2 //打開文件時,文件指針在開頭,pointer = 0;
3 raf.write(byte);//write方法只會寫一個字節,同時直接指針指向下一個位置
4 int b = raf.read();//每次讀一個字節,java中每一個字符佔用兩個字節,使用右移8位的方式分次寫入
5 raf.seek(指針位置);//移動指針
6 raf.close();//文件讀寫完必定要關閉,不然可能會有意想不到的後果
在文件下載文件的時候,這種方式有很大的好處,每一個線程下載文件的一部分,
          而後再拼接在一塊兒,迅雷就是使用的這種方式,會記錄指針的位置
 
4、字節流(InputStream、OutputStream,兩個都是抽象類)
         一、I/O流用來處理設備之間的數據傳輸
            InputStream抽象了應用程序讀取數據的方式
             OutputStream抽象了應用程序寫出數據的方式
         二、EOF = End  讀到 -1 就讀到結尾
         三、輸入流的基本方式主要是讀
              int b = in.read();//讀取一個字節無符號填充到int第八位,-1是EOF
              in.read(byte[] buf);//讀入多個字節填充的字節數組
         四、輸出流的基本方式主要是寫
              out.write(int b);
              out.write(byte[] buf);
         五、FileInputStream具體實現了文件的讀取操做
                while((b=in.read())!=-1){讀一個文件}
                in.close();//必定要記得關閉流釋放系統資源
                批量讀取(速度很是快,效率高) vs. 單字節讀取(不適合讀大文件,效率很低)
          六、FileOutputStream具體實現了向文件中寫數據的操做
                是刪除文件從新建立,仍是在原文件上追加內容,看構造方法
                本身實現文件的copy操做
                out.flush();
                out.close();
          七、數據輸入輸出流DataOutputStream/DataInputStream
                對流功能的擴展,是一個包裝類,能夠更加方便的讀取int,long,字符等類型數據,本質是使用的一種裝飾模式實現的
         八、字節緩衝流BufferedInputStream/BufferedOutputStream
                 爲I/O提供了帶緩衝區的操做,這種流模式提升了I/O的性能     
                 .write();
                 .flush();//刷新緩衝區,不然寫入不到文件中
                 .close();
 
5、字符流(參考API)
       一、Java爲何引入字符流?
             操做文本時,尤爲是包含中文字符等非ASCII碼的字符會很不方便
             字符流 = 字節流+編碼
             因此,要對編碼問題很是清楚    
       二、java的文本(char)是16位無符號整數,是字符的Unicode編碼(雙字節)    
          文件是byte byte byte……的數據序列
          文本文件是文本序列按照某種編碼方式序列化爲byte的存儲
       三、字符流(Reader Writer)操做的是文本文件
          一次處理一個字符,字符的底層仍然是基本的字節序列
          InputStreamReader 完成byte流按照編碼解析爲char流
          OutputStreamWriter 提供char流按照編碼解析成byte流
       四、文件讀寫流  FileReader、FileWriter
             無法設置編碼,必須回到字符流設置編碼
       五、字符流的過濾器BufferedReader、BufferedWriter、PrintWriter
             readLine  能夠一次讀一行,一次寫一行
             能夠設置編碼,不識別換行,單獨寫出換行操做
 
6、對象的序列化和反序列化
         一、將Object對象轉換成byte序列,反之叫對象的反序列化
         二、序列化流(ObjectOutputStream),是過濾流---writeObject()
            反序列化流(ObjectInputStream),    ----readObject
         三、序列化接口(Serializable)
            對象必須實現序列化接口,才能進行序列化,不然將出現異常
            這個接口沒有任何方法,只是一個標準,是標記接口
            
            對象序列化後,若是對再次對類文件修改,那麼反序列化的時候就會出問題,那麼怎麼解決呢?
            須要在類中設置序列版本id,惟一標記,這樣不管怎麼修改讀取的時候都不會再有問題   serialVersionUID

 

 
         四、transient關鍵字
               聲明的元素不會進行JVM默認的序列化,也能夠本身完成這個元素的序列化
               網絡中傳輸時,並非全部的元素都是有必要傳輸的,尤爲是要考慮節約網絡流量的時候
               在有些狀況下,能夠幫助咱們提升性能(ArrayList在數組沒有放滿的時候,只把有效元素序列化)
         五、序列化中 子類和父類構造函數的調用問題
             父類實現了序列化接口,子類不須要再次實現,就能進行序列化    
             對子類對象進行反序列化操做時,若是其父類沒有顯示的實現序列化接口,那麼其父類的構造函數會被調用
 
7、輸入輸出流的一些包裝類
       一、打印流
               PrintStream  :字節打印流
               PrintWriter  :字符打印流
               集成了Print()格式化輸出方法,能夠操做任意類型的數據
       二、標準輸入輸出流
               System類的in、out字段
               默認輸入設備是鍵盤,輸出設備是顯示器
               
               標準IO重定向
               System.setIn(InputStream);
               //重定向輸出能夠將打印到控制檯的日誌寫到文件
               System.setOut(PrintStream);
               System.err(PrintStream);
 
       三、進程控制
              在Java內部執行其餘操做系統的程序,並要求控制這些程序的輸入輸出時
              向OSExecute.command()傳遞一個command字符串    
Process process = new ProcessBuilder(command.split(" ")).start();

OSExecute.command("javap test");

//javap是java的一個反編譯程序

8、IO操做過程當中異常處理編程

        
       本身編程要用try-catch-finally包圍起來,若是有異常儘可能處理,千萬不要僅僅是用printStackTrace()打印棧信息,在finally中進行流的關閉(判斷引用不爲空的話關閉),以確保必定能獲得執行
相關文章
相關標籤/搜索