18岁末年禁止进入

    1. <th id="axuoa"><sup id="axuoa"></sup></th>

      <code id="axuoa"><em id="axuoa"></em></code>
    2. <code id="axuoa"></code>

      <object id="axuoa"></object>

      當前位置:首頁 > 學習資源 > 講師博文 > Java字節流使用方法

      Java字節流使用方法 時間:2018-03-01      來源:未知

      在java中我們使用輸入流來向一個字節序列對象中寫入,使用輸出流來向輸出其內容。C語言中只使用一個File包處理一切文件操作,而在java中卻有著60多種流類型,構成了整個流家族?此讫嫶蟮捏w系結構,其實只要使用適合的方法將其分門別類,就顯得清晰明了了。而我準備將其按照處理文件類型的不同,分為字節流類型和字符流類型。

      基類流

      其實始終有人搞不清楚到底InputStream是讀還是OutputStream是讀。其實很簡單就可以記住,你把你自己想象為是一個程序,InputStream對你來說是輸入,也就是你要從某個地方讀到自己這來,而OutputStream對你來說就是輸出,也就是說你需要寫到某個地方。這樣就可以簡單的區分輸入輸出流。InputStream是一個輸入流,也就是用來讀取文件的流,抽象方法read讀取下一個字節,當讀取到文件的末尾時候返回 -1。如果流中沒有數據read就會阻塞直至數據到來或者異常出現或者流關閉。這是一個受查異常,具體的調用者必須處理異常。除了一次讀取一個字節,InputStream中還提供了read(byte[]),讀取多個字節。read(byte[])其實默認調用的還是read(byte b[], int off, int len)方法,表示每讀取一個字節就放在b[off++]中,總共讀取len個字節,但是往往會出現流中字節數小于len,所以返回的是實際讀取到的字節數。

      接下來是一些高級的用法,skip方法表示跳過指定的字節數,來讀取。調用這種方法需要知道,一旦跳過就不能返回到原來的位置。當然,我們可以看到還有剩下的三種方法,他們一起合作實現了可重復讀的操作。mark方法在指定的位置打上標記,reset方法可以重新回到之前的標記索引處。但是我們可以想到,它一定是在打下mark標記的地方,使用字節數組記錄下接下來的路徑上的所有字節數據,直到你使用了reset方法,取出字節數組中的數據供你讀取(實際上也不是一種能夠重復讀,只是用字節數組記錄下這一路上的數據而已,等到你想要回去的時候將字節數組給你重新讀取)。

      OutputStream是一種輸出流,具體的方法和InputStream差不多,只是,一個讀一個寫。但是,他們都是抽象類,想要實現具體的功能還是需要依賴他們的子類來實現,例如:FileInputStream/FileOutputStream等。

      Java字節流

      文件字節流

      FileInputStream繼承與InputStream,主要有以下兩個構造方法:

      public FileInputStream(String name)

      public FileInputStream(File file)

      第一種構造方法傳的是一個字符串,實際上是一個確定文件的路徑,內部將此路徑封裝成File類型,調用第二種構造方法。第二中構造方法,直接綁定的是一個具體的文件。FileInputStream 的內部方法其實和父類InputStream中定義的方法差不多,我們通過一個讀文件的實例來演示用法。

      FileInputStream fin = new FileInputStream("hello.txt");

      byte[] buffer = new byte[1024];

      int x = fin.read(buffer,0,buffer.length);

      String str = new String(buffer);

      System.out.println(str);

      System.out.println(x);

      fin.close();

      結果意料之中,調用了read方法將hello.txt中的內容讀到字節數組buffer中,然后通過String類構造方法將字節數組轉換成字符串。返回實際上讀取到的字節數13。(10個字母+兩個空格+一個字符串結束符)FileOutputStream繼承父類OutputStream,主要方法代碼如下:

      private final boolean append;

      public FileOutputStream(String name)

      public FileOutputStream(String name, boolean append)

      public FileOutputStream(File file)

      public FileOutputStream(File file, boolean append)

      private native void writeBytes(byte b[], int off, int len, boolean append)

      public void write(byte b[]) throws IOException

      FileOutputStream的一些基本的操作和FileInputStream類似,只是一個是讀一個是寫。我們主要要知道,append屬性是指定對于文件的操作是覆蓋方式(false),還是追加方式(true)。下面通過一個實例演示其用法:

      FileOutputStream fou = new FileOutputStream("hello.txt");

      String str = "Walker_YAM";

      byte[] buffer = str.getBytes("UTF-8");

      fou.write(buffer,0 ,buffer.length);

      fou.close();

      如我們所料,字符串"Walker_YAM"將會被寫入hello.txt,由于沒有指定append,所以將會覆蓋hello.txt中的所有內容。

      動態字節數組流

      在我們上述的文件讀取流中,我們定義 byte[] buffer = new byte[1024];,buffer數組為1024,如果我們將要讀取的文件中的內容有1025個字節,buffer是不是裝不下?當然我們也可以定義更大的數組容量,但是從內存的使用效率上,這是低效的。我們可以使用動態的字節數組流來提高效率。

      ByteArrayInputStream的內部使用了類似于ArrayList的動態數組擴容的思想。

      protected byte buf[];

      protected int count;

      public ByteArrayInputStream(byte buf[])

      public ByteArrayInputStream(byte buf[], int offset, int length)

      public synchronized int read()

      public synchronized int read(byte b[], int off, int len)

      ByteArrayInputStream內部定義了一個buf數組和記錄數組中實際的字節數,read方法也很簡單,讀取下一個字節,read(byte b[], int off, int len) 將內置字節數組讀入目標數組。實際上,整個ByteArrayInputStream也就是將一個字節數組封裝在其內部。為什么這么做?主要還是為了方便參與整個InputStream的體系,復用代碼。ByteArrayOutputStream的作用要比ByteArrayInputStream更加的實際一點:

      protected byte buf[];

      protected int count;

      public ByteArrayOutputStream() { this(32); }

      public ByteArrayOutputStream(int size)

      private void ensureCapacity(int minCapacity)

      public synchronized void write(byte b[], int off, int len)

      public synchronized void writeTo(OutputStream out)

      public synchronized byte toByteArray()[]

      public synchronized String toString()

      和ByteArrayInputStream一樣,內部依然封裝了字節數組buf和實際容量count,通過構造方法可以指定內置字節數組的長度。主要的是write方法,將外部傳入的字節數組寫到內置數組中,writeTo方法可以理解為將自己內置的數組交給OutputStream 的其他子類使用。toByteArray和toString則會將內置數組轉換成指定類型返回。下面我們利用他們解決剛開始說的效率問題。

      FileInputStream fin = new FileInputStream("hello.txt");

      ByteArrayOutputStream bou = new ByteArrayOutputStream();

      int x = 0;

      while((x = fin.read()) !=-1){

      bou.write(x);

      }

      System.out.println(bou.toString());

      從hello文件中每讀取一個字節寫入ByteArrayOutputStream 中,我們不用擔心hello文件太大而需要設置較大的數組,使用ByteArrayOutputStream 動態增加容量,如果添加字節即將超過容量上限,進行擴充(往往是指數級擴充)

      裝飾者字節流

      上述的流都是直接通過操作字節數組來實現輸入輸出的,那如果我們想要輸入一個字符串類型或者int型或者double類型,那還需要調用各自的轉字節數組的方法,然后將字節數組輸入到流中。我們可以使用裝飾流,幫我們完成轉換的操作。我們先看DataOutputStream。

      public DataOutputStream(OutputStream out)

      public synchronized void write(byte b[], int off, int len)

      public final void writeBoolean(boolean v)

      public final void writeByte(int v)

      public final void writeShort(int v)

      public final void writeInt(int v)

      public final void writeDouble(double v)

      簡單的列舉了一些方法,可以看到,DataOutputStream只有一個構造方法,必須傳入一個OutputStream類型參數。(其實它的內部還是圍繞著OutputStream,只是在它的基礎上做了些封裝)。我們看到,有writeBoolean、writeByte、writeShort、writeDouble等方法。他們內部都是將傳入的 boolean,Byte,short,double類型變量轉換為了字節數組,然后調用從構造方法中接入的OutputStream參數的write方法。

      緩沖流

      在這之前,我們讀取一個字節就要將它寫會磁盤,這樣來回開銷很大,我們可以使用緩沖區來提高效率,在緩沖區滿的時候,或者流關閉時候,將緩沖區中所有的內容全部寫會磁盤。BufferedInputStream和BufferedOutputStream也是一對裝飾流,我們先看看BufferedInputStream:

      private static int DEFAULT_BUFFER_SIZE = 8192;

      protected volatile byte buf[];

      protected int pos;

      protected int count;

      public BufferedInputStream(InputStream in)

      public BufferedInputStream(InputStream in, int size)

      public synchronized int read()

      public synchronized void mark(int readlimit)

      public synchronized void reset()

      一樣也是裝飾類流,第一種構造方法要求必須傳入InputStream類型參數,DEFAULT_BUFFER_SIZE 指定了默認的緩沖區的大小,當然還可以使用第二種構造方法指定緩沖區的大小(當然不能超過上界),read方法讀取的時候會將數據讀入內部的緩沖區中,當然緩沖區也是可以動態擴容的。

      BufferedInputStream bi = new BufferedInputStream(new FileInputStream("hello.txt"));

      bi.read();

      bi.read();

      bi.read();

      bi.read();

      System.out.println(bi.available());

      BufferedOutputStream和它是逆操作,不在贅述。這種緩沖字節流可以很大程度上提高我們的程序執行的效率,所以一般在使用別的流的時候都會包裝上這層緩沖流。

      上一篇:三層架構實現Java Web案例

      下一篇:java抽象類的作用

      戳我查看2020年嵌入式每月就業風云榜

      點我了解華清遠見高校學霸學習秘籍

      猜你關心企業是如何評價華清學員的

      干貨分享
      相關新聞
      前臺專線:010-82525158 企業培訓洽談專線:010-82525379 院校合作洽談專線:010-82525379 Copyright © 2004-2020 北京華清遠見科技發展有限公司 版權所有 ,京ICP備16055225號,京公海網安備11010802025203號

      回到頂部

      18岁末年禁止进入

      1. <th id="axuoa"><sup id="axuoa"></sup></th>

        <code id="axuoa"><em id="axuoa"></em></code>
      2. <code id="axuoa"></code>

        <object id="axuoa"></object>