黑馬程序員_

--------------------ASP.Net+Android+IOS開發.Net培訓、期待與您交流! --------------------


1.字節流

字符流:Writer,Reader 主要是用來操作的是文本文件

字節流:InputStream,OutputStream主要是用來操作的是媒體文件,例如:圖片,音樂,電影…等。但是也可以操作文件。

 

如果用字符流操作媒體文件的話,複製文件的話:也能複製,只是複製後的圖片不能看,因爲查看的編碼是不一樣的,

不管是讀還是寫,都不需要刷新緩衝,除非用到了緩衝對象。

2. FileOutStream

     操作文件,向文本文件中寫入數據,其沒有寫入字符串耳朵方法,有字節數組的寫入,所以我們要把字符串轉換成數組。然後寫入。

 

 

importjava.io.FileNotFoundException;
importjava.io.FileOutputStream;
importjava.io.IOException;
importjava.io.OutputStream;
 
public classOutStreamDemo {
      public static void main(String[]args)  {
           OutputStream out=null;
           try {
                 out=new FileOutputStream("F:\\demo.txt");
                 out.write("helloworld".getBytes());//寫入數據,把字符串轉換爲字節數組
           } catch (IOException e) {
                 e.printStackTrace();
           }finally{
                 if(out!=null){
                      try {
                            out.close();
                      } catch (IOException e) {
                            e.printStackTrace();
                      }
                 }
           }
      }
 
}


3.     FileInputStream

讀取文件,有三種方法,

第一種:一個一個字符的讀取,

第二種:字節數組的讀取。

第三種:使用available()方法,讀取到文件的總大小,然後定義相同大小的字節數組,讀取一次即可,但是加入文件過大,大於了虛擬的內存的大小,那麼就會加載不進去,所以最好的辦法是定義恰當合適的數組,然後循環讀取。
 

          1.  單個字節讀取

使用的read()方法,進行循環讀取。

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
 
public class InputStreamDemo {
  public static void main(String[] args) {
    InputStream in = null;
    try {
      in = new FileInputStream("F:\\demo.txt");
      /* 這個爲一個一個的讀取,使用read()方法,然後讀取到的字符的ASCII碼,到結尾就返回-1*/
      int r = -1;
      while ((r = in.read()) != -1) {//開始讀取
         System.out.print((char) r);
      }
    } catch (IOException e) {
      e.printStackTrace();
    }finally{
      if(in!=null){
         try {
           in.close();//關閉流
         } catch (IOException e) {
           e.printStackTrace();
         }
      }
    }
  }
 
}


         2.  字節數組讀取

定義恰當的數組,然後循環讀取 使用的read(byte [] b)
然後轉換成字符串,返回。

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
 
public class InputStreamDemo {
  public static void main(String[] args) {
    InputStream in= null;
    try {
      in= new FileInputStream("F:\\demo.txt");
      /* 使用字節數組讀取,然後轉成字符串。到結尾就返回-1*/
      byte [] b=new byte[1024];
      int len=-1;
      while ((len = in.read(b)) != -1) {//開始讀取
         System.out.print(new String(b,0,len));
      }
    } catch (IOException e) {
      e.printStackTrace();
    }finally{
      if(in!=null){
         try {
           in.close();//關閉流
         } catch (IOException e) {
           e.printStackTrace();
         }
      }
    }
  }
 
}


 

           3.  固定數組大小

使用的available()方法,讀取到文件的大小,然後定義相應的大小的字節數組,如果文件小的話,可以這樣使用,但是文件很大,超過了虛擬機的申請的內存,那麼就會導致加載不進入,所以最好的方法是是喲第二種方法,定義合適的字節數組的大小。
 

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
 
public class InputStreamDemo {
  public static void main(String[] args) {
    InputStream in = null;
    try {
      in = new FileInputStream("F:\\demo.txt");
      /* 使用字節數組讀取,數組的大小用:available()方法定,然後轉成字符串。到結尾就返回-1 */
      byte[] b = new byte[in.available()];
      int len = in.read(b);
      System.out.print(new String(b, 0,len));
 
    } catch (IOException e) {
      e.printStackTrace();
    } finally {
      if (in != null) {
         try {
           in.close();// 關閉流
         } catch (IOException e) {
           e.printStackTrace();
         }
      }
    }
  }
 
}


 

4. 複製圖片

     使用的InputStream和OutputStream

     步驟:

     1.使用讀取流InputStream,與要讀取的圖片關聯。

     2.定義寫入流,定義好複製到的位置和圖片的名稱。

     3.然後一邊讀取一邊寫入,循環讀取和循環寫入。使用的是數組讀取和寫入。

     4.最後關閉流。

   擴展:複製後的文件名稱可以改變也可以不變,格式也可以改變,jpg或者bmp.或者其他的格式都可以

 

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
 
public class OutAndInputStreamDemo {
  public static void main(String[] args) {
    InputStream in = null;// 讀取流字節流
    OutputStream out = null;// 寫入流字節流
    try {
      in = new FileInputStream("F:\\A\\1.jpg");// 與複製的圖片關聯起來
      out = new FileOutputStream("F:\\B\\1.bmp");// 與複製到的目的關聯起來,這裏的圖片的名稱可以與原來的相同,也可以不一樣
      byte[] b = new byte[1024];// 定義字節數組,並指定長度
      int l = -1;
      while ((l = in.read(b)) != -1) {// 讀取
         out.write(b, 0, l);// 寫入,讀多少寫入多少,所以用 write(b,0,len)
      }
      System.out.println("複製成功");
    } catch (IOException e) {
      e.printStackTrace();
    } finally {
      if (in != null) {
         try {
           in.close();// 關閉讀取流
         } catch (IOException e) {
           System.out.println("讀取流關閉失敗");
         }
         if (out != null) {
           try {
             out.close();// 關閉寫入流
           } catch (IOException e) {
             System.out.println("寫入流關閉失敗");
           }
         }
      }
 
    }
  }
 
}
結果:
複製成功


5. 字節流的緩衝

      字符流:Writer,Reader

             BufferedWriter和BufferedReader

字節流:InputStream,OutputStream體文

                    BufferedInputStream和BufferedOutputStream

 

字節流的緩衝和字符流的花衝使用方法是類似的,用的對象是BufferedInputStream和BufferedOutputStream,他們增強了字節流的讀取和寫入效率。

         1.  利用緩衝對象複製MP3文件

 

package www.fuxi.IO;
 
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
 
public class BufferedStreamDemo {
  public static void main(String[] args) {
    BufferedInputStream bis = null;// 讀取緩衝流
    BufferedOutputStream bos = null;// 寫入緩衝流
    try {
      bis = new BufferedInputStream(new FileInputStream("F:\\A\\1.mp3"));// 要複製的MP3文件
      bos = new BufferedOutputStream(new FileOutputStream("F:\\B\\1.mp3"));// 複製到的目的地
      byte[] b = new byte[1024];
      int len = 0;
      while ((len = bis.read(b)) != -1) {// 讀取
         bos.write(b, 0, len);// 寫入
      }
      System.out.println("複製成功");
    } catch (Exception e) {
      e.printStackTrace();
    } finally {
      if (bis != null) {
         try {
           bis.close();// 關閉讀取緩衝對象流
         } catch (IOException e) {
           e.printStackTrace();
         }
         if (bos != null) {
           try {
             bos.close();// 關閉寫入緩衝對象流
           } catch (IOException e) {
             e.printStackTrace();
           }
         }
      }
    }
  }
 
}
結果:
複製成功


         2.  模擬讀取緩衝區

 

import java.io.IOException;
import java.io.InputStream;
 
public class MyBufferedInputStream {
   privateInputStream in = null;
   private intcount = 0;// 計數器
   private intpos = 0;// 指針
   private byte[]bu = new byte[1024];// 封裝的字節數組
 
   publicMyBufferedInputStream(InputStream in) {
        this.in =in;
   }
 
   public intMyRead() throws IOException {
 
        if (count== 0) {// 說明此時緩衝區中沒有數據,可能是緩衝區中還沒有開始讀取,或者是緩衝區中數據讀取完畢
              count= in.read(bu);// 向緩衝區中讀取數據
              if(count < 0) {
                   return-1;// 這裏返回的是int類型的-1
              }
              pos=0;//每次把指針都初始化
              byteb = bu[pos];
              count--;//計數器減一
              pos++;//指針加一
              returnb & 0xff;// 這裏b是byte類型,自動提升爲整形,但是前面補充的是全是1,爲了防止當讀取道德byte數據爲11111111時,&上0xff,那麼使前面的是0,那麼這樣額可以是原數據不變,又能避免字節數據是-1的情況
 
        } elseif(count>0){
              byteb = bu[pos];
              count--;//計數器減一
              pos++;//指針加一
              returnb & 0xff;// 這裏b是byte類型,自動提升爲整形,但是前面補充的是全是1,爲了防止當讀取道德byte數據爲11111111時,&上0xff,那麼使前面的是0,那麼這樣額可以是原數據不變,又能避免字節數據是-1的情況
        }
        return-1;
   }
 
   public voidmyClose() throws IOException {
        in.close();
   }
}
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
/*
 *測試類,也是複製MP3*/
public class BufferedStreamDemo {
  public static void main(String[] args) {
    MyBufferedInputStream bis = null;// 讀取緩衝流
    BufferedOutputStream bos = null;// 寫入緩衝流
    try {
      bis = new MyBufferedInputStream(new FileInputStream("F:\\A\\1.mp3"));// 要複製的MP3文件
      bos = new BufferedOutputStream(new FileOutputStream("F:\\B\\1.mp3"));// 複製到的目的地
      // byte[] b = new byte[1024];
      int r = 0;
      while ((r = bis.MyRead()) != -1) {// 讀取
         bos.write(r);// 寫入
      }
      System.out.println("複製成功");
    } catch (Exception e) {
      e.printStackTrace();
    } finally {
      if (bis != null) {
         try {
           bis.myClose();// 關閉讀取緩衝對象流
         } catch (IOException e) {
           e.printStackTrace();
         }
         if (bos != null) {
           try {
             bos.close();// 關閉寫入緩衝對象流
           } catch (IOException e) {
             e.printStackTrace();
           }
         }
      }
    }
  }
 
}
 
結果:複製成功


 

注意點:在MyRead()方法中return 返回的必須寫b&0xff,因爲這樣byte類型的提升爲整形後,可以保證原數據保持不變,把原來的數據前面相當於添加的0.

例如:

byte  : 11111111  這是-1

自動提升爲整形後的數據是

        1111111111111111 11111111 11111111 此時這是-1

那麼當byte類型的數據是八個1的時候,那麼直接返回b,那麼提升爲整形後是四個八個1,那麼還是-1,所以程序直接結束,讀取完畢,解決方法是,要是在前面補充的是全是0的話,那麼原數據不變沒這樣也避免的讀取-1的情況。

      1111111111111111 11111111 11111111

&     00000000 00000000 00000000 11111111 這是255,

-----------------------------------------------------------------

      0000000000000000 00000000 11111111

 

所以這樣結果就是我們想要的數據,既避免了讀取byte是11111111的缺點,同時還保證了原數據不變。

Read方法是byte類型的提升,從1個字節提升爲整形爲四個字節。Write方法是把4個字節變成了1個字節,值去最後的一個字節。所以複製後的文件的大小和原來的大小一下,而不是其4倍的大小。

6. 鍵盤讀取

  

   import java.io.IOException;
import java.io.InputStream;
 
public class ClassDemo {
  public static void main(String[] args) throws IOException {
    /*
     * InputStream in“標準”輸入流:讀取的設備是鍵盤 PrintStream out“標準”輸出流。輸出到控制檯
     */
    /*
     * 我們可以循環輸入,當輸入爲over時候,結束輸入
     */
    InputStream in = System.in;
    StringBuilder bu= new StringBuilder();
    while (true) {
      int ch = in.read();
      if (ch == '\r')
         continue;
      if (ch == '\n') {
         String s = bu.toString();
         if ("over".equals(s))// 如果輸入的是over,那麼結束輸入
           break;
         System.out.println("輸入的內容是:" + s);
         bu.delete(0,bu.length());
      } else
         bu.append((char) ch);
    }
 
  }
 
}
結果:
aa
輸入的內容是:aa
bb
輸入的內容是:bb
cc
輸入的內容是:cc
over

 


--------------------ASP.Net+Android+IOS開發.Net培訓、期待與您交流! --------------------

 


發佈了46 篇原創文章 · 獲贊 3 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章