InputStream類的實現

gudesheng發表於2008-01-03

      我們知道,java是一種解釋型的語言。它的虛擬機器幫助我們把.class檔案變成機器能夠識別的機器語言。

     當然,做為一個應用層開發的程式設計師,我們沒必要去看JVM的實現程式碼,如果你有興趣寫自己的虛擬機器,自己寫一種新的語言出來,你也可以去看。

     我們現在關心的是:在JVM規範的基礎上的java基本類庫的實現機制,從而從本質上認識到java語言的規範和功能。

   因為最近一直在做網路通訊相關的東西,這裡也給大家解釋一下自己對通訊協議的認識:

   其實所謂的通訊協議,就是雙方約定俗成的一些規範和需要完成的一些功能,當然,如果有興趣,你同樣也可以開發屬於自己的通訊協議。不過這個工作就比較麻煩了,要有差錯管理,流量控制,資料校驗等複雜的過程。如果你是從事協議開發的,那就另說了。我們學java的當然沒必要來了解這些,因為底層的一些東西往往是用更加低階的語言來完成的,以方便和機器的操作。

   這和我們的IE瀏覽器很相似,因為它也按照約定和實現方法接受HTML格式的資料流,然後解析顯示出來。同樣,我們的手機瀏覽器也只能解析WML格式的資料流。如果可能,你也可以開發出一種解析HTML格式資料流的手機瀏覽器。這就是通訊的本質,通訊的雙方按照約定俗成的東西去交流資訊。

  在我們的工作中,一般沒必要去改寫這些底層的通訊協議和其功能。我們要做的就是把附加的資料資訊增加到相應的資料包中。在端對端的開發中,另外一端再逐層的解析資料包,把附加資訊一層層的過濾,最終得到我們想要的東西。然後做介面的重新整理,這就是所謂的網路通訊。其實沒什麼神祕性,只要你從低層上了解了它,很簡單,也很容易操作。

  其實做網路遊戲也一樣,Client和Server按照實現約定好的協議把附加的資訊追加到資料包的頭部或者資料實體內(具體視通訊方法不同而不同)。然後雙方通過不斷的解析和傳送約定格式的資料包來進行通訊和介面的重新整理。

   我們先看J2SE自帶的InputStream的原始碼:

package java.io; //所處的位置,因此我們在用的時候要import匯入

public abstract class InputStream { //很明顯是個抽象類,因此不能new一個InputStream出來

   
    private static final int SKIP_BUFFER_SIZE = 2048;
    private static byte[] skipBuffer;

    public abstract int read() throws IOException;

   public int read(byte b[], int off, int len) throws IOException {
       if (b == null) {  //如果傳入的位元組陣列為空,丟擲NullPointerException異常,因此這個方法應該用在try{}裡
           throw new NullPointerException();
       } else if ((off < 0) || (off > b.length) || (len < 0) ||

((off + len) > b.length) || ((off + len) < 0)) { //一些出界的可能性,如果出界丟擲異常
     throw new IndexOutOfBoundsException();
 } else if (len == 0) { //如果你要讀的資料長度為0,那麼read()方法返回0,什麼也讀不到
     return 0;
 }

 int c = read();
 if (c == -1) { //如果偏移量超出位元組陣列b時,此方法返回-1

     return -1;
 }
 b[off] = (byte)c;  //從此可見read方法是從off位置可以正式讀取的,即:off位置的元素屬於read讀的第一個

 int i = 1;
 try {
     for (; i < len ; i++) {
  c = read();
  if (c == -1) {
      break;
  }
  if (b != null) {
      b[off + i] = (byte)c;
  }
     }
 } catch (IOException ee) {
 }
 return i;  //返回的是讀取到的位元組數
    }

 

   public int read(byte b[]) throws IOException {  //過載上面的方法
       return read(b, 0, b.length);
    }

public long skip(long n) throws IOException {

 long remaining = n;
 int nr;
 if (skipBuffer == null)
     skipBuffer = new byte[SKIP_BUFFER_SIZE];

 byte[] localSkipBuffer = skipBuffer;
  
 if (n <= 0) {
     return 0;
 }

 while (remaining > 0) {
     nr = read(localSkipBuffer, 0,
        (int) Math.min(SKIP_BUFFER_SIZE, remaining));
     if (nr < 0) {
  break;
     }
     remaining -= nr;
 }
 
 return n - remaining;
    }

 

    public int available() throws IOException {
                 return 0;
    }

public void close() throws IOException {}

 public synchronized void mark(int readlimit) {}

public synchronized void reset() throws IOException {
 throw new IOException("mark/reset not supported");
    }

 

 public boolean markSupported() {
              return false;
    }

}



Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=761760


相關文章