public void readArr() { // 明確文件 File file = new File("D:/net.txt"); // 構建流的對象 InputStream inputStream = null; try { inputStream = new FileInputStream(file); // 聲名緩沖數組 int i; byte[] bytes = new byte[5]; while ((i = inputStream.read(bytes)) != -1) { for (int j = 0; j < i; j++) { System.out.print((char)bytes[j]); } } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { try { if (inputStream != null) { inputStream.close(); } } catch (IOException e) { e.printStackTrace(); } } }
在使用InputStream讀取文件時,發現在使用while循環讀取文件時,它會自動的按順序讀取文件的內容,這是為什么呢?首先我們看看官方的API文檔解釋:
/** * Reads the next byte of data from the input stream. The value byte is * returned as an <code>int</code> in the range <code>0</code> to * <code>255</code>. If no byte is available because the end of the stream * has been reached, the value <code>-1</code> is returned. This method * blocks until input data is available, the end of the stream is detected, * or an exception is thrown. * * <p> A subclass must provide an implementation of this method. * * @return the next byte of data, or <code>-1</code> if the end of the * stream is reached. * @exception IOException if an I/O error occurs. */ public abstract int read() throws IOException
大概意思就是,每次調用InputStream.read()方法,就從輸入流中讀取一個字節的數據,並返回這個字節。如果讀取內容到達文件末尾,那么就返回-1。

文件流FileInputStream的讀取是單向的,也就是說讀取順序是按照文件中的數據存儲書序來的。另外,
通過.read()方法讀出來的數據是個臨時變量,java會自動在堆中為其分配一個內存空間,但是當.read()方法執行結束,垃圾回收器會立刻將其刪除,因此在程序中.read(byte[] bytes)方法中的bytes參數才是實際上是用來存儲讀取出來數據的參數。如果文件保存了10個字節的數據,而bytes長度為8,那么inputStream會按照每8個字節讀一次文件,在此例中會讀取兩次,並且最終輸出結果會有問題。這是因為第二次讀取出來的兩個字節會按照讀取順序依次填充在bytes數組的前兩位,而后面6位元素並不會改變。
public void readStr() { // 寫文件 OutputStream outputStream = null; // 讀文件 InputStream inputStream = null; try { outputStream = new FileOutputStream(file); inputStream = new FileInputStream(file); createFile(); String str = "helloWorld"; outputStream.write(str.getBytes()); outputStream.flush(); byte[] bytes = new byte[8]; // read()按內容存儲順序進行讀取,從第一個字節到最后,讀取出來的內容保存在bytes數組中,如果數組的長度不夠,則接下來讀取出來的內容會被依次覆蓋 while (inputStream.read(bytes) != -1) { System.out.println("我在循環!"); for (byte b:bytes) { System.out.print((char)b); } System.out.println(); } } catch (IOException e) { e.printStackTrace(); } finally { try { outputStream.close(); inputStream.close(); } catch (IOException e) { e.printStackTrace(); } } }
輸出結果:我在循環!
helloWor
我在循環!
ldlloWor