<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      Java網絡編程的Java流介紹

      前言

      網絡程序所做的很大一部分工作都是簡單的輸入輸出:將數據字節從一個系統移動到另一個系統。Java的I/O建立于流(stream)之上。輸入流讀取數據,輸出流寫入數據。過濾器流(filter)流可以串聯到輸入或輸出流上。讀寫數據時過濾器可以修改數據(加密或壓縮),或者只是提供額外的方法,將讀/寫的數據轉換為其他格式。閱讀器(reader)和書寫器(writer)可以串鏈到輸入流和輸出流上,允許程序讀/寫文本而不是字節。

      輸出流

      Java的基本輸出流類是:java.io.OutputStream;

      這個類中提供了寫入數據所需的基本方法,如下:

      public abstract void write(int b) throws IOException;
      public void write(byte b[]) throws IOException
      public void write(byte b[], int off, int len) throws IOException
      public void flush() throws IOException
      public void close() throws IOException

      但是我們平時使用它的子類來實現向某種特定介質寫入數據。例如:FileOutputStream等,它的子類都是通過裝飾模式來實現一些特定的功能的。OutputStream的基本方法是write(int b)。這個方法接受一個0到255之間的整數作為參數,將對應的字節寫入到輸出流中。雖然此方法接受一個int作為參數,但它實際上會寫入一個無符號字節,因為java沒有無符號字節數據類型,所以這要使用int來代替。無符號字節和有符號字節之間唯一的真正區別在于解釋。它們都由8個二進制組成,write方法將int寫入一個網絡連接時,線纜上只會放8個二進制位。如果將一個超出0~255的int傳入write方法,將協議這個數的最低字節,其他3個字節將被忽略。因為每次寫入一個字節效率不高,所以就又提供了兩個可以傳入字節數組的方法,write(byte[])、write(byte b[],int off,int len)。

      與網絡硬件中緩存一樣,流還可以在軟件中得到緩沖,即直接用java代碼緩存。在寫入數據完成后,刷新(flush)輸出流非常重要。因為flush()方法可以強迫緩沖的流發送數據,即使緩沖區還沒有滿,以此來打破流一直等待著緩沖區滿了才會發送數據的狀態。

      最后,當結束一個流操作時,要通過調用它的close()方法將其關閉。關閉流會釋放與整個流關聯的所有資源,如果流來自網絡連接,這個連接也會被關閉。長時間未關閉一個流,可能會泄漏文件句柄、網絡端口和其他資源。所以在Java6以及更早的版本中,是在一個finally塊中關閉流。但是Java7引入了try width resources 可以簡化關閉流的操作,只需要把流定義在try的參數中即可。

      如下所示:

      try(OutputStream out = new FileOutputStream("D:/temp/test.txt")){
           // 處理輸出流
      
      }catch (IOException e){
          e.printStackTrace();
      }

      因為Java會對try塊參數表中 聲明的所有AutoCloseable對象自動調用close()。Java中的流相關的類基本上都直接或間接的實現了AutoCloseable接口。

      輸入流

      Java的基本輸出流類是:java.io.InputStream;

      這個類提供了將數據讀取為原始字節所需要的基本方法。如下:

      public abstract int read() throws IOException;
      public int read(byte b[]) throws IOException
      public int read(byte b[], int off, int len) throws IOException
      public long skip(long n) throws IOException 
      public int available() throws IOException 
      public void close() throws IOException

       InputStream的基本方法是沒有參數的read()方法。此方法從輸入流的源中讀取1字節數據,作為一個0到255的int返回,流的結束通過返回-1來表示。read()方法會等待并阻塞其后任何代碼的執行,直到有1字節的數據可供讀取。輸入和輸出可能很慢,所以如果成行在做其他重要工作,要盡量將I/O放在單獨的線程中。

      一次讀取1字節的效率也不高,因此,有兩個重載的read()方法,可以用從流中讀取的多字節的數據填充一個指定的數組:read(byte[] input)和read(byte[] input, int offset,int length)。當read的時候如果遇到IOException或網絡原因只讀取到了一部分,這個時候就會返回實際讀取到的字節數。

      例如:

      int bytesRead = 0;
      int bytesToRead = 1024;
      byte[] input = new byte[bytesToRead];
      while (bytesRead<bytesToRead){
             bytesRead += in.read(input,bytesRead,bytesToRead - bytesRead);
      }

      上面這段代碼就是沒有考慮到有可能流會中斷導致讀取的數據永遠讀不出來,所以要防止這種事情出現需要先測試read()的返回值,然后再增加到byteRead中

      如下所示:

      int bytesRead = 0;
      int bytesToRead = 1024;
      byte[] input = new byte[bytesToRead];
      while (bytesRead<bytesToRead){
        int result = in.read(input,bytesRead,bytesToRead - bytesRead);
        if(result == -1) break;
        bytesRead += result;
      }

      可以使用available()方法來確定不阻塞的情況下有多少字節可以讀取。它會返回可讀取的最少字節數。事實上還能讀取更多字節,至少可以讀取available()建議的字節數。

      如下:

      int bytesAvailable = in.available();
      byte[] input = new byte[bytesAvailable];
      int bytesRead = in.read(input,0,bytesAvailable);
      //讀取到數據后,去執行其他部分

      在少數情況下,你可能希望跳過數據不進行讀取。skip()方法會完成這項任務。

      與輸出流一樣,一旦結束對輸入流的操作,應當調用close()方法將其關閉。這會釋放這個流關聯的所有資源。

      InputStream類中還有3個不經常用的方法,

      public synchronized void mark(int readlimit)
      public synchronized void reset() throws IOException
      public boolean markSupported()

      為了重新讀取數據,要用mark()方法標記流的當前位置,在以后某個時刻可以用reset()方法把流重置到之前標記的位置。在嘗試使用標記和重置之前,要堅持markSupported()方法是否返回true。如果返回true,那么這個流確實支持標志和重置,否則,mark()會什么都不做,而reset()將拋出一個IOException異常。

      過濾器流

      過濾器由兩個版本:過濾器流(filte stream)以及閱讀器(reader)和書寫器(writer)

      每個過濾器輸出流都有與java.io.OutputStream相同的write()、close()和flush()方法。每個過濾器輸入流都有與java.io.InputStream相同的read()、close()和available()方法。

      過濾器通過其構造函數與流連接。

      FileInputStream iin = new FileInputStream("test.txt");
      BufferedInputStream bin = new BufferedInputStream(iin);

      這種情況下如果混合調用連接到同一個源的不同流,這可能會違反過濾器流的一些隱含約定。大多數情況下應當只使用鏈中最后一個過濾器進行實際的讀/寫。

      可以用如下方式:

      InputStream iin = new FileInputStream("test.txt");
      iin = new BufferedInputStream(iin);

      緩沖流

      BufferedOutputStream類將寫入的數據存儲在緩沖區中,直到緩沖區滿了或者執行了flush方法。然后將數據一次全部寫入底層輸出流。在網絡連接中,緩沖網絡輸出通常會帶來巨大的性能提升。

      BufferedInputStream類也有一個作為緩沖區的保護字節數組,當調用某個流的read()方法時,它首先嘗試從緩沖區獲得請求的數據。當緩沖區沒有數據時,流才從底層的源中讀取數據。這時,它會讀取盡可能多的數據存入緩沖區,而不管是否馬上需要所有這些數據。不會立即用到的數據可以在以后調用read()時讀取。當從本地磁盤中讀取文件時,從底層流中讀取幾百字節的數據與讀取1字節數據幾乎一樣快。因此,緩沖可以顯著提升性能。

      BufferedOutputStream有兩個構造函數,BufferedInputStream也是有兩個構造函數:

      public BufferedInputStream(InputStream in)
      public BufferedInputStream(InputStream in, int size) 
      
      public BufferedOutputStream(OutputStream out)
      public BufferedOutputStream(OutputStream out, int size) 

      PrintStream

      PrintStream類是大多數程序員都會遇到的第一個過濾器輸出流,因為System.out就是一個PrintStream。還可以使用下面兩個構造函數將其他輸出流串鏈到打印流:

      public PrintStream(OutputStream out)
      public PrintStream(OutputStream out, boolean autoFlush)

      如果autoFlush參數為true,那么每次寫入1字節數組或換行,或者調用println()方法時,都會刷新輸出流。除了平常的write()、flush()和close()方法,PrintStream還有9個重載的print()方法和10個重載的println方法:

      public void print(boolean b)
      public void print(char c)
      public void print(int i)
      public void print(long l)
      public void print(float f)
      public void print(double d)
      public void print(char s[])
      public void print(String s) 
      public void print(Object obj)
      public void println()
      public void println(boolean x)
      public void println(char x) 
      public void println(int x)
      public void println(long x) 
      public void println(float x) 
      public void println(double x) 
      public void println(char x[])
      public void println(String x)
      public void println(Object x) 

      每個print()方法都將其參數以可見的方式轉換為一個字符串,再用默認的編碼方式把字符串寫入底層輸出流。println()方法也完成相同操作,但會在所寫的行末尾追加一個與平臺有關的行分隔符。

      在網絡編程中應盡量避免使用PrintStream。

      PrintStream第一個問題,println()輸出是與平臺有關的。

      PrintStream第二個問題,會假定使用所在平臺的默認編碼方式。

      PrintStream第三個問題,會吞掉了所有異常。

      數據流

      DataInputStream和DataOutputStream類提供了一些可以用二進制格式讀/寫Java的基本數據類型和字符串。

      DataOutputStream類提供下面11種方法,可以寫入特定的Java數據類型。

      public final void writeBoolean(boolean v) throws IOException 
      public final void writeByte(int v) throws IOException
      public final void writeShort(int v) throws IOException
      public final void writeChar(int v) throws IOException
      public final void writeInt(int v) throws IOException
      public final void writeLong(long v) throws IOException
      public final void writeFloat(float v) throws IOException
      public final void writeDouble(double v) throws IOException 
      public final void writeBytes(String s) throws IOException
      public final void writeChars(String s) throws IOException 
      public final void writeUTF(String str) throws IOException

      前面的8個方法,都按照實際參數的類型長度來寫數據的,最后三個方法有些特別,writeChars()方法只是對String參數迭代處理,將各個字符按順序寫為一個2字節的big-endian Unicode字符。writeBytes()方法迭代處理String參數,但只是寫入每個字符的低字節。

      writeChars和writeBytes都不會對輸出流的字符串的長度編碼。因此,你無法真正區分原始字符和作為字符串一部分的字符。writeUTF()方法則包括了字符串的長度。它將字符串本身用Unicode UTF-8編碼的一個變體進行編碼。

      除了這些寫入二進制數字和字符串的方法,DataOutputStream當然還有所有OutputStream類都有的平常的write()、flush()、和close()方法。

      DataInputStream與DataOutputStream是互補的。DataOutputStream寫入的每一種數據格式,DataInputStream都可以讀取。此外DataInputStream還有通常read()、available()、skip()和close()方法,以及讀取整個字節數組和文本行的方法。所以DataInputStream的內容就不寫了。

      書寫器

      Writer是以字符流的方式書寫數據,它是一個抽象類,有兩個保護類型的構造函數。與OutputStream類似,Writer類從不直接使用;相反,會通過他的某個子類以多態方式使用。它有5個write()方法,另外還有flush()和close()方法。

      protected Writer()
      protected Writer(Object lock) 
      abstract public void write(char cbuf[], int off, int len) throws IOException
      public void write(int c) throws IOException
      public void write(char cbuf[]) throws IOException 
      public void write(String str) throws IOException 
      public void write(String str, int off, int len) throws IOException 
      bstract public void flush() throws IOException
      abstract public void close() throws IOException

      abstract public void write(char cbuf[], int off, int len)方法是基礎方法,其他四個write()都是根據它實現的。子類至少覆蓋整個方法以及flush()和close(),
      但是為了提供更高效的實現方法,大多數子類還覆蓋了其他一些write()方法。

      例如:給定一個Writer對象w,可以這樣寫入字符串“Jimoer”:

      char[] jimoer = {'J','i','m','o','e','r'};
      w.write(jimoer,0,jiomer.length);

      也可以用其他write()方法完成同樣的任務:

      Writer w = new OutputStreamWriter(out);
      w.write(jiomer);
      for(int i=0;i<jimoer.length;i++){
           w.write(jiomer[i]);
      }
      w.write("Jimoer");
      w.write("Jimoer",0,5);

      所有這些例子表述都是同樣的事情,只不過方式有所不同。

      書寫器可以緩沖,有可能直接串鏈到BufferedWriter,也有可能直接鏈入。為了強制將一個寫入提交給輸出介質,需要調用flush()方法。

      OutputStreamWriter

      OutputStreamWriter是Writer的最重要的具體子類。OutputStreamWriter會從Java程序中接收字符。會根據指定的編碼方式將這些字符轉換為直接,并寫入底層輸出流。

      構造函數指定了要寫入的輸出流和使用的編碼方式:

      public OutputStreamWriter(OutputStream out, String charsetName)
              throws UnsupportedEncodingException
          {
              super(out);
              if (charsetName == null)
                  throw new NullPointerException("charsetName");
              se = StreamEncoder.forOutputStreamWriter(out, this, charsetName);
          }

      除了構造函數,OutputStream只有通常的Writer方法,還有一個返回對象編碼方式的方法:

      public String getEncoding()

      閱讀器

      Reader是一個抽象類,從不直接使用,只通過子類來使用。有三個read()方法,另外還有skip()、close()、ready()、mark()、reset()和markSupported()方法:

      protected Reader()
      protected Reader(Object lock) 
      abstract public int read(char cbuf[], int off, int len) throws IOException
      public int read() throws IOException 
      public int read(char cbuf[]) throws IOException
      public long skip(long n) throws IOException
      public boolean ready() throws IOException
      public boolean markSupported()
      public void mark(int readAheadLimit) throws IOException 
      public void reset() throws IOException 
      abstract public void close() throws IOException

      這里面的方法大多數都與Writer中方法能對應上,read()方法以int型(從0到65,535)返回一個單一的Unicode字符或讀到流結束時返回-1。

      InputStreamReader是Reader的最重要的具體子類。InputStreamReader從其底層輸入流中讀取字節。然后根據指定的編碼發那個還是將字節轉為字符,并返回這些字符。

      構造函數如下:

      public InputStreamReader(InputStream in) 
      public InputStreamReader(InputStream in, String charsetName)
              throws UnsupportedEncodingException
      public InputStreamReader(InputStream in, Charset cs) 
      public InputStreamReader(InputStream in, CharsetDecoder dec)

      如果沒有指定編碼方式,就使用平臺的默認編碼方式。如果指定了一個位置的編碼方式,會拋出UnsupportedEncodingException異常。

      過濾閱讀器和書寫器

      InputStreamReader和OutputStreamWriter類就相當于輸入和輸出流之上的裝飾器,把面向字節的接口改為面向字符的接口。完成之后就可以將其他面向字符的過濾器放在使用java.io.FilterReader和java.io.FilterWriter類的閱讀器或書寫器上。

      BufferedReader和BufferedWriter也有與閱讀器和書寫器關聯的常用方法,如read()、ready()、write()和close()。這兩個類都有兩個構造函數,可以將BufferedReader或BufferedWriter串鏈到一個底層閱讀器或書寫器,并設置緩沖區的大小。如果沒有設置大小,則使用默認的大小8192字符:

      public BufferedReader(Reader in, int sz) 
      public BufferedReader(Reader in)
      public BufferedWriter(Writer out)
      public BufferedWriter(Writer out, int sz) 

      BufferedReader類還有一個readLine()方法,它讀取一行文本,并作為一個字符串返回:

      public String readLine() throws IOExceptioin

      這個方法可以替代DataInputStream中國已經廢棄的readLine()方法,它與該方法的行為基本相同。主要區別在于,通過BufferedReader串鏈到InputStreamReader,可以用正確的字符集讀取行,而不是采用平臺的默認編碼方式。

      BufferedWriter類增加了一個其超類所沒有的新方法,名為newLine(),也用于寫入一行:

      public void newLine() throws IOException

      這個方法向輸出插入一個與平臺有關的行分隔符字符串。

      PrintWriter

      PrintWriter類用戶取代Java1.0的PrintStream類,它能正確地處理多字節字符集和國際化文本。除了構造函數,PrintWriter類也有與PrintStream幾乎相同的方法集。

      public PrintWriter (Writer out)
      public PrintWriter(Writer out,boolean autoFlush) 
      public PrintWriter(OutputStream out)
      public PrintWriter(OutputStream out, boolean autoFlush) 
      public PrintWriter(String fileName) throws FileNotFoundException 
      private PrintWriter(Charset charset, File file) throws FileNotFoundException
      public PrintWriter(String fileName, String csn)
              throws FileNotFoundException, UnsupportedEncodingException
      public PrintWriter(File file) throws FileNotFoundException 
      public PrintWriter(File file, String csn)
              throws FileNotFoundException, UnsupportedEncodingException
      public void flush() 
      public void close()
      public boolean checkError() 
      public void write(int c) 
      public void write(char buf[], int off, int len)
      public void write(char buf[])
      public void write(String s, int off, int len) 
      public void write(String s)
      public void print(boolean b)
      public void print(char c)
      public void print(int i)
      public void print(long l)
      public void print(float f)
      public void print(double d)
      public void print(char s[])
      public void print(String s)
      public void print(Object obj)
      public void println()
      public void println(boolean x)
      public void println(char x)
      public void println(int x) 
      public void println(long x) 
      public void println(float x) 
      public void println(double x) 
      public void println(char x[])
      public void println(String x)
      public void println(Object x) 
      public PrintWriter printf(String format, Object ... args) 

      這些方法的行為大多數與PrintStream中相同。只有4個write()方法有所例外,它們寫入字符而不是字節。

       

      posted @ 2018-11-28 22:28  紀莫  閱讀(1116)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 亚洲成av人片色午夜乱码| 无套内谢少妇毛片aaaa片免费| 亚洲精品国产成人| 亚洲欧美综合一区二区三区| 欧美叉叉叉bbb网站| 色综合色综合综合综合综合| 阳高县| 国产综合一区二区三区麻豆| 一卡二卡三卡四卡视频区| 亚洲精品国产精品国在线| 成人一区二区不卡国产| 亚洲尤码不卡av麻豆| 国产在线线精品宅男网址| 久久大香伊蕉在人线免费AV | 午夜久久水蜜桃一区二区| 国产精品自拍午夜福利| 高清自拍亚洲精品二区| 漂亮的保姆hd完整版免费韩国| 精品国产国语对白主播野战| 日韩av天堂综合网久久| 97精品尹人久久大香线蕉| 亚洲精品色哟哟一区二区| 日韩欧美国产aⅴ另类| 福安市| 国产高清无遮挡内容丰富| 日韩人妻一区中文字幕| 亚洲最大国产成人综合网站| 激情在线一区二区三区视频| 久久精品人妻无码专区| 日韩一区二区三区在线观院| 宝贝腿开大点我添添公视频免| 少妇高潮灌满白浆毛片免费看| 亚洲免费最大黄页网站| 久久精品免视看国产成人| 欧美最猛性xxxxx大叫| 色吊丝一区二区中文字幕| 中文字幕亚洲国产精品| 亂倫近親相姦中文字幕| 野花香视频在线观看免费高清版| 人妻少妇中文字幕久久| 国产色无码专区在线观看|