在處理文件輸入流時,經過調用available()方法來獲取還有多少字節能夠讀取,根據該數值建立固定大小的byte數組,從而讀取輸入流的信息。java
FileInputStream fi = new FileInputStream("C:/Users/Administrator/Desktop/yy.txt"); //1. read() 逐字節讀取 /* int i = 0; byte[] bytes = new byte[fi.available()]; while(fi.available() > 0){ bytes[i] = (byte) fi.read(); i++; }*/ //2. read(byte b[]) 一次讀取 byte[] bytes = new byte[fi.available()]; fi.read(bytes);
fi.close(); System.out.println(Arrays.toString(bytes));
可是在處理網絡流(socket)時,經過available()方法對輸入流進行長度判斷,數值爲0,這意味着對方發送的流中無數據,但實際上並不是如此。數組
緣由在於:網絡
網絡通信每每是間斷性的,一串字節每每分幾批進行發送。例如對方發來字節長度100的數據,本地程序調用available()方法有時獲得0,有時獲得50,有時能獲得100,大多數狀況下是0。這多是對方尚未響應,也多是對方已經響應了,可是數據尚未送達本地。也許分3批到達,也許分兩批,也許一次性到達。socket
詳細解釋參考OSI網絡7層結構:spa
咱們進行的數據接收只是基於應用層,網絡傳輸的最上層,數據從一端到另外一端傳輸的時候,會在傳輸層分解成適合的數據包。傳輸層(Transport Layer)是OSI 模型中最重要的一層。傳輸協議同時進行流量控制或是基於接收方可接收數據的快慢程度規定適當的發送速率。除此以外,傳輸層按照網絡能處理的最大尺寸將較長的數據包進行強制分割。例如,以太網沒法接收大於1500 字節的數據包。發送方節點的傳輸層將數據分割成較小的數據片,同時對每一數據片安排一序列號,以便數據到達接收方節點的傳輸層時,能以正確的順序重組。該過程即被稱爲排序。工做在傳輸層的一種服務是 TCP/IP 協議套中的TCP(傳輸控制協議),另外一項傳輸層服務是 IPX/SPX 協議集的 SPX(序列包交換)。code
InputStream的available()方法的做用是返回此輸入流在不受阻塞狀況下能讀取的字節數。網絡流與文件流不一樣的關鍵就在因而否「受阻」二字,網絡socket流在讀取時若是沒有內容read()方法是會受阻的,因此從socket初始化的輸入流的available也是爲零的,因此要read一字節後再使用,這樣可用的字節數就等於 available + 1。但文件讀取時read()通常是不會受阻的,由於文件流的可用字節數 available = file.length(),而文件的內容長度在建立File對象時就已知了。 orm
因此調用網絡流(socket)的available()方法前,必定記得要先調用read()方法,這樣才能避免獲取爲0的不正確狀況。對象
//將接收到的數據存到字節數組bytes int firstByte = inputStream.read(); int length = inputStream.available(); byte[] bytes = new byte[length+1]; bytes[0] = (byte)firstByte; inputStream.read(bytes,1,length);
另外,在文件上載和表單提交的過程當中,能夠使用 request.getContentLength()方法代替InputStream.available()方法,經過調用 request.getContentLength() 獲得 Content-Length ,並定義一個與 Content-Length 大小相等的字節數組 buffer,從HttpServletRequest 的實例 request 中獲得一個 InputStream, 並把它讀入 buffer 中。而後使用 FileOutputStream 將 buffer 寫入指定文件。blog
// ReceiveServlet.java import java.io.*; import javax.servlet.*; import javax.servlet.http.*; //示例程序:記錄下Form提交上來的數據,並存儲到Log文件中 public class ReceiveServlet extends HttpServlet { public void doPost(HttpServletRequest request,HttpServletResponse response) throws IOException, ServletException { //1 int len = request.getContentLength(); byte buffer[] = new byte[len]; //2 InputStream in = request.getInputStream(); int total = 0; int once = 0; while ((total < len) && (once >=0)) { once = in.read(buffer,total,len); total += once; } //3 OutputStream out=new BufferedOutputStream( new FileOutputStream("Receive.log",true)); byte[] breaker="\r\nNewLog: -------------------->\r\n".getBytes(); System.out.println(request.getContentType()); out.write(breaker,0,breaker.length); out.write(buffer); out.close(); } }