大型互聯(lián)網(wǎng)項(xiàng)目視頻 本公眾專(zhuān)注于為廣大Java初學(xué)者和愛(ài)好者以及熱愛(ài)編程的菜鳥(niǎo)提供學(xué)習(xí)交流平臺(tái),共同成長(zhǎng)。 如果您發(fā)現(xiàn)什么錯(cuò)誤、遺漏或不明的地方,可以通過(guò)文章下留言、群內(nèi)討論或私撩小編提出意見(jiàn)反饋,當(dāng)然小編會(huì)給這些奉獻(xiàn)的朋友分享Java 大型互聯(lián)網(wǎng)項(xiàng)目實(shí)戰(zhàn)視頻資料(不定期更新視頻資料) ,希望與大家一同成長(zhǎng)?。?! 在java語(yǔ)言中提供了很多輸入與輸出流,使我們方便了對(duì)數(shù)據(jù)進(jìn)行操作,其中管道流是一種特殊的流,用于在不同線程間直接傳輸數(shù)據(jù)。一個(gè)線程發(fā)送到輸出管道,另一個(gè)線程從輸入管道中讀取數(shù)據(jù)。通過(guò)使用管道,實(shí)現(xiàn)不同線程間的通訊,而無(wú)須借助臨時(shí)文件之類(lèi)的東西了。 在jdk中提供了4個(gè)類(lèi)來(lái)使用線程間可以進(jìn)行通訊: 一堆字節(jié)流管道流和一堆字符管道流 PipedInputStreamPipedOutputStreamPipedReaderPipedWriter
一般大家都是知道的只要是流基本上都是成對(duì)成對(duì)出現(xiàn)的,一邊寫(xiě)入一遍讀取?,F(xiàn)在首先講解一下PipedInputStream和PipedOutputStream這對(duì)管道流使用步驟。 建立管道輸入端和輸出端的連接,必須首先創(chuàng)建一個(gè)PipedOutputStream對(duì)象,然后創(chuàng)建一個(gè)PipedInputStream對(duì)象。如下: PipedOutputStream out = null; PipedInputStream in = null; 對(duì)象建立好以后使用connect()方法將二者建立連接 out.connect(in); 該方法在PipedOutputStream 、PipedInputStream當(dāng)中都有,隨便調(diào)用那個(gè)來(lái)建立連接都可以,但注意只能建立一次連接,重復(fù)建立會(huì)拋異常。 不使用connect()方法也是可以建立連接的,方法如下: out = new PipedOutputStream(in ); 一旦建立了管道,就可以像操作文件一樣對(duì)管道進(jìn)行數(shù)據(jù)讀寫(xiě)。 下面線程配合管道流的使用代碼編寫(xiě)。 /** * 寫(xiě)入線程 */ public class PipedThreadOut implements Runnable { /** * 管道輸出流 */ private PipedOutputStream out; /** * 構(gòu)造函數(shù) * @param out */ public PipedThreadOut(PipedOutputStream out) { this.out = out; } /** * 寫(xiě)入數(shù)據(jù) */ private void write() { String data = '我是pipedOutputStream流,寫(xiě)入數(shù)據(jù)了?。?!'; try { this.out.write(data.getBytes()); System.out.println('寫(xiě)入數(shù)據(jù)為:'+data);
} catch (IOException e) { e.printStackTrace(); }finally { try { this.out.close();//關(guān)閉輸出流 } catch (IOException e) { e.printStackTrace(); } } } @Override public void run() { //開(kāi)始寫(xiě)入 this.write(); } }
/** * 讀取線程 */ class PipedThreadIn implements Runnable { /** * 管道輸出流 */ private PipedInputStream in; /** * 構(gòu)造函數(shù) * @param in */ public PipedThreadIn(PipedInputStream in) { this.in = in; } /** * 讀取數(shù)據(jù) */ private void read() { //定義一個(gè)緩沖區(qū) byte[] b = new byte[1024]; //記錄讀取字節(jié)數(shù) int len; String data = ''; try { //開(kāi)始讀取 while ((len = this.in.read(b)) > 0) { data += new String(b,0,len); } System.out.println('讀取數(shù)據(jù)為:' + data); } catch (IOException e) { e.printStackTrace(); }finally { try { this.in.close();//關(guān)閉讀取流 } catch (IOException e) { e.printStackTrace(); } } System.out.println('====================================='); } @Override public void run() { //開(kāi)始讀取 this.read(); } }
調(diào)用代碼 public class PipedThreadTest { public static void main(String[] args) throws IOException, InterruptedException { //創(chuàng)建寫(xiě)入流 PipedOutputStream out = new PipedOutputStream(); //創(chuàng)建讀取流 PipedInputStream in = new PipedInputStream(); //為寫(xiě)入和讀取建立連接 out.connect(in); //創(chuàng)建寫(xiě)入流線程 Thread outThread = new Thread(new PipedThreadOut(out)); //創(chuàng)建讀取流線程 Thread inThread = new Thread(new PipedThreadIn(in)); //啟動(dòng)線程 outThread.start(); Thread.sleep(1000); inThread.start(); } }
結(jié)果: 寫(xiě)入數(shù)據(jù)為:我是pipedOutputStream流,寫(xiě)入數(shù)據(jù)了?。?! 讀取數(shù)據(jù)為:我是pipedOutputStream流,寫(xiě)入數(shù)據(jù)了?。?! =====================================
解釋一下代碼編寫(xiě)的過(guò)程 1.首先創(chuàng)建一個(gè)輸出管道的runnable的實(shí)現(xiàn)類(lèi)作為寫(xiě)入數(shù)據(jù)線程類(lèi)使用,寫(xiě)入數(shù)據(jù)需要傳入一個(gè)輸出管道流對(duì)象。
2. 在創(chuàng)建一個(gè)輸入管道的runnable的實(shí)現(xiàn)類(lèi)作為讀取數(shù)據(jù)的線程類(lèi)使用,讀取數(shù)據(jù)需要傳入一個(gè)輸入管道流對(duì)象。
3. 在測(cè)試類(lèi)創(chuàng)建一個(gè)輸出流對(duì)象和一個(gè)輸入流對(duì)象。
4. 在創(chuàng)建2個(gè)線程將輸出和輸入對(duì)象傳到各自對(duì)應(yīng)的runnable的實(shí)現(xiàn)類(lèi)中
5. 最后啟動(dòng)2個(gè)線程。
注意:一定要將輸入和輸出流簡(jiǎn)歷連接connect 字符管道流和字節(jié)管道流幾乎是一模一樣的使用,只需要將輸入字節(jié)流修改成字符流,以及將輸出字節(jié)流修改為輸出字符流,并且需要將讀取緩沖區(qū)的byte數(shù)組修改為char數(shù)組即可。直接看代碼吧?。?! /** * 寫(xiě)入線程 */ public class PipedThreadOut implements Runnable { /** * 管道輸出流 */ private PipedWriter out; /** * 構(gòu)造函數(shù) * @param out */ public PipedThreadOut(PipedWriter out) { this.out = out; } /** * 寫(xiě)入數(shù)據(jù) */ private void write() { String data = '我是pipedWrite流,寫(xiě)入數(shù)據(jù)了!??!'; try { this.out.write(data); System.out.println('寫(xiě)入數(shù)據(jù)為:'+data);
} catch (IOException e) { e.printStackTrace(); }finally { try { this.out.close();//關(guān)閉輸出流 } catch (IOException e) { e.printStackTrace(); } } } @Override public void run() { //開(kāi)始寫(xiě)入 this.write(); } }
/** * 讀取線程 */ class PipedThreadIn implements Runnable { /** * 管道輸出流 */ private PipedReader in; /** * 構(gòu)造函數(shù) * @param in */ public PipedThreadIn(PipedReader in) { this.in = in; } /** * 讀取數(shù)據(jù) */ private void read() { //定義一個(gè)緩沖區(qū) char[] b = new char[1024]; //記錄讀取字節(jié)數(shù) int len; String data = ''; try { //開(kāi)始讀取 while ((len = this.in.read(b)) > 0) { data += new String(b,0,len); } System.out.println('讀取數(shù)據(jù)為:' + data); } catch (IOException e) { e.printStackTrace(); }finally { try { this.in.close();//關(guān)閉讀取流 } catch (IOException e) { e.printStackTrace(); } } System.out.println('====================================='); } @Override public void run() { //開(kāi)始讀取 this.read(); } }
測(cè)試運(yùn)行代碼 public class PipedThreadTest { public static void main(String[] args) throws IOException, InterruptedException { //創(chuàng)建寫(xiě)入流 PipedWriter out = new PipedWriter(); //創(chuàng)建讀取流 PipedReader in = new PipedReader(); //為寫(xiě)入和讀取建立連接 out.connect(in); //創(chuàng)建寫(xiě)入流線程 Thread outThread = new Thread(new PipedThreadOut(out)); //創(chuàng)建讀取流線程 Thread inThread = new Thread(new PipedThreadIn(in)); //啟動(dòng)線程 outThread.start(); Thread.sleep(1000); inThread.start(); } }
運(yùn)行結(jié)果: 寫(xiě)入數(shù)據(jù)為:我是pipedWrite流,寫(xiě)入數(shù)據(jù)了?。?! 讀取數(shù)據(jù)為:我是pipedWrite流,寫(xiě)入數(shù)據(jù)了?。?! =====================================
好了管道流比較簡(jiǎn)單,和前面學(xué)習(xí)的流差不多,只是配合線程使用了一下。
|