国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學(xué)院 > 開發(fā)設(shè)計 > 正文

Java數(shù)據(jù)流——企業(yè)級數(shù)據(jù)流分析(組圖)

2019-11-18 12:24:00
字體:
供稿:網(wǎng)友

  輸入輸出流的概念在java 1.0中首次被引入。與多媒體流不同,Java數(shù)據(jù)流以一種標(biāo)準(zhǔn)的方式進(jìn)行工作,將數(shù)據(jù)寫入目的地和從源讀取數(shù)據(jù)。如:文件,套接字,甚至鍵盤和屏幕(System.in和System.out)都是作為可以用輸入輸出流進(jìn)行通訊的源和目的的普通的例子。實際上,一些對象,如套接字,可以同時既是目的也是源。
  
  Java消息服務(wù)是企業(yè)級應(yīng)用在一個分布式的環(huán)境中相互通訊的標(biāo)準(zhǔn)方式。雖然這是一個眾所周知并大量驗證的方法,但是它是復(fù)雜的和有時顯得很粗笨的消息驅(qū)動框架,它缺少了一些簡單的流框架就可以提供的能力。MantaRay,一個開源的數(shù)據(jù)消息項目(JMS提供者),基于點對點,無服務(wù)端的架構(gòu),它通過融合了JMS和數(shù)據(jù)流兩者的優(yōu)點來解決上述的問題。
  
  這篇文章將會討論隱藏在流概念中的能力和由MantaRay開源項目開發(fā)的企業(yè)級數(shù)據(jù)流,一種新型的流,它的目的地和源是JMS的topic和queue。
  
  輸入輸出流的能力
  
  概括

  
  流的最重要的能力特性在于,無論目的和源是什么,通訊API始終保持一致。寫入一個套接字和寫入一個文件是一樣的。一個FileOutputStream對象可以專門為文件的操作提供額外的功能,但基礎(chǔ)的讀寫仍然是一樣的。結(jié)果是假如你不使用額外的功能,那么你就可以簡單的替換掉源/目的而不需要改變你的代碼。
  
  圖1顯示了流是如何使用的
  
 Java數(shù)據(jù)流——企業(yè)級數(shù)據(jù)流分析(組圖)(圖一)
  圖1.使用流

  
  針對每種目的的流API是相同的和很原始的。舉例,InputStream類的read()方法的返回值是一個在0-255之間的int。出于這個原因,Java提供了一組寫入這些流更多復(fù)雜數(shù)據(jù)的工具。這些工具包括像writer和reader這樣的幫助類,也有包裝原始流的包裝流。這些工具將在下一節(jié)討論。
  
  流交換和改變
  
  另一個強(qiáng)大的特性是在一個流之上包裝另一個流。假如你想寫數(shù)據(jù)到一個文件但希望數(shù)據(jù)是被壓縮的,你只需簡單地創(chuàng)建一個FileOutputStream對象并將它包裝在一個ZipOutputStream對象內(nèi)。然后你寫數(shù)據(jù)到ZipOutputSream,它會壓縮數(shù)據(jù)并將它傳遞給FileOutputStream,它會將其寫入到一個物理文件中。類似的,你可以使用FileInputStream和ZipInputStream對象從一個.zip文件中讀出內(nèi)容。
  
  實際上,你可以將多個流鏈接起來。比如,你可將一個SocketOutputStream包裝在一個CipherOutputStream對象內(nèi)用來加密數(shù)據(jù),再包裝在一個ZipInputStream對象內(nèi)用來壓縮數(shù)據(jù)。當(dāng)數(shù)據(jù)從一個流傳遞到另一個流時, 每一個對象都在數(shù)據(jù)上進(jìn)行自己的操作。
  
  圖2顯示了包裝流的一個例子
  
 Java數(shù)據(jù)流——企業(yè)級數(shù)據(jù)流分析(組圖)(圖二)
  圖2.包裝流

  
  MantaRay的企業(yè)級流
  
  為什么需要企業(yè)級流?

  
  與大多數(shù)流工作于物理的IO組件不同,MantaRay企業(yè)級流工作于JMS的隊列(queue)和主題(topic)之上。JMS是通過隊列和主題傳遞消息的一個面向消息的標(biāo)準(zhǔn),通常用在企業(yè)級應(yīng)用環(huán)境中。
  
  舉例來說,讓我們看看兩個想通過隊列來進(jìn)行通訊的應(yīng)用。一個應(yīng)用向隊列中發(fā)送一條消息,另一個應(yīng)用則接收這條消息。下面的代碼演示了這一過程,使用JMS 1.02實現(xiàn)。
  
  // 發(fā)送代碼:javax.jms.QueueConnectionFactory conFactory = new
  ...
  // look up in JNDI or create an instance
  // 在JNDI中查找或創(chuàng)建一個實例javax.jms.QueueConnection con
  = conFactory.createQueueConnection();
  // 創(chuàng)建一個非事務(wù)的自動確認(rèn)的sessionjavax.jms.QueueSession sendSession
  = con.createQueueSession(false
  ,Session.AUTO_ACKNOWLEDGE);javax.jms.Queue sendQueue
  = sendSession.createQueue (sQueue);javax.jms.QueueSender sender
  = sendSession.createSender(sendQueue);javax.jms.TextMessage msg
  = sendSession.createTextMessage();msg.setText( "some text" );sender.send( msg,
  javax.jms.DeliveryMode.NON_PERSISTENT,
  javax.jms.Message.DEFAULT_PRIORITY,MESSAGE_TTL);
  // 接收代碼:javax.jms.QueueConnectionFactory conFactory = new ...
  // 在JNDI中查找或創(chuàng)建一個實例javax.jms.QueueConnection con
  = conFactory.createQueueConnection();
  // 創(chuàng)建一個非事務(wù)的自動確認(rèn)的sessionjavax.jms.QueueSession receiveSession
  = con.createQueueSession(false
  ,Session.AUTO_ACKNOWLEDGE);javax.jms.Queue receiveQueue
  = receiveSession.createQueue (rQueue);javax.jms.QueueReceiver qReceiver
  = receiveSession.createReceiver(receiveQueue);javax.jms.TextMessageMessage
  =(TextMessageMessage) qReceiver.receive();
  
  正如你所看到的,不僅代碼有點復(fù)雜,而且它也是面向消息而非面向流的。當(dāng)一個用戶向企業(yè)級流中寫入數(shù)據(jù)時,流會將數(shù)據(jù)剪切成包并將他們包裝到一個JMS消息中。然后將消息發(fā)送到預(yù)設(shè)的隊列或主題中,那里消息將被作為輸入流處理,解包數(shù)據(jù),并為目的端用戶作好讀取的預(yù)備。
  
  圖3 顯示了數(shù)據(jù)是如何在MantaRay企業(yè)級流中被處理的。
  
 Java數(shù)據(jù)流——企業(yè)級數(shù)據(jù)流分析(組圖)(圖三)
  圖3.MantaRay企業(yè)級流中數(shù)據(jù)處理的過程

  
  因為企業(yè)級流擴(kuò)展了InputStream和OutputStream對象,就象一個套接字或文件的Input/OutputStream做的那樣,你可以將它們像流一樣使用,從而釋放出流所特有的能力。
  
  ·因為提供了所有流可以共享的接口,所以它們使用起來非常簡單。
  ·你可將它們與其它流包裝在一起從而獲得如壓縮和加密那樣的擴(kuò)展功能。
  ·你不用擔(dān)心將數(shù)據(jù)拆分包,緩存的分配或其它的低層次的針對數(shù)據(jù)傳遞的問題
  
  使用企業(yè)級流
  
  JMS隊列都是點對點的通訊。當(dāng)在一個隊列上使用企業(yè)級流時,在同一個隊列上應(yīng)該只有一個輸出流和一個輸入流。雖然大多數(shù)的JMS提供者,包括MantaRay,在同一個隊列上啟用了多個生產(chǎn)者和消費者,但這并沒有在JMS標(biāo)準(zhǔn)中定義,因此當(dāng)在一個隊列上使用企業(yè)級流時,這就是一種誤用。原因在于,特定隊列上的一條消息只能傳遞給一個消費者;因此,假如有多個消費者,將會‘偷’走其它人的消息。
  
  JMS主題定義了多對多的通訊。當(dāng)企業(yè)級流使用一個主題用作源或目的時,同一個主題只能有一個發(fā)布者,同時可以有多個訂閱者。原因在于,同一個主題上的多個發(fā)布者只會攪亂數(shù)據(jù),并向訂閱者發(fā)送無意義的輸出。
  
  但是,實事上基于主題的可以有多個訂閱者,可以使用類似廣播的一對多的通訊。輸出流的用戶不需要為每一個對端治理一個輸出流。而是,用戶只需簡單地將數(shù)據(jù)發(fā)送到輸出流中,那么所有的主題訂閱者將會收到消息。
  
  企業(yè)級流使用connect方法來綁定到一個主題或隊列上。只有當(dāng)流聯(lián)接以后,你才能從中寫入或讀取。基于隊列的流,輸出流產(chǎn)生的數(shù)據(jù)存放在隊列中,直到有輸入流來‘消費’它。因為有存儲數(shù)據(jù)的能力,聯(lián)接的順序是不重要的。輸出流可以聯(lián)接后送入數(shù)據(jù),輸入流則可以在任何時候聯(lián)接,并取走從頭開始的所有數(shù)據(jù)。使用主題作為輸入流時有些不同,主題只能收到當(dāng)它聯(lián)接以后產(chǎn)生的數(shù)據(jù)。雖然這在某些情況下并不是個問題(比如,一個持續(xù)的CPU使用報告),但在某些情況下卻很重要(比如,文件傳輸)。
  
  MantaRay企業(yè)級流示例
  
  提供—閱讀式圖表

  
  考慮一個圖型數(shù)據(jù)提供者組件,它產(chǎn)生持續(xù)的數(shù)據(jù)—可以是內(nèi)存使用率,股票價格,工廠輸出或是地球上某一時刻火星人的數(shù)目。這種數(shù)據(jù)需要顯示在一個叫做圖表閱讀器的幾個不同的位置。
  
  因為數(shù)據(jù)是持續(xù)的并且通訊是一對多的類型,這個任務(wù)可以被MantaRay企業(yè)級流輕松的解決。
  
  圖4顯示了圖表閱讀器組件
  
 Java數(shù)據(jù)流——企業(yè)級數(shù)據(jù)流分析(組圖)(圖四)
  圖4.圖表閱讀器組件

  
  下面是圖表數(shù)據(jù)提供者組件一個簡短的示例:
  
  import org.mr.api.blocks.MantaOutputStream;
  .../*** 創(chuàng)建隨機(jī)的數(shù)據(jù)并將它發(fā)送給圖表閱讀器
  */public class GraphFeeder {
  public static void main(String[] args)
  throws Exception {
  // 創(chuàng)建一個具有4字節(jié)容量的小包的輸出流,這個容量可以告訴流要將
  // 信息切成小包
  MantaOutputStream out =
  new MantaOutputStream(4);
  // 將企業(yè)級輸出流聯(lián)接到一個叫g(shù)raph的主題上
  out.connect("graph",
  MantaOutputStream.TOPIC);
  // 將數(shù)據(jù)包裝在DataOutputStream中,這樣我們可以輕松地寫入整數(shù)
  DataOutputStream dos =
  new DataOutputStream(out);
  int currentStatus = 0;
  for(int rounds =0 ;rounds < 30000
  ;rounds++ ){
  // 在圖表中產(chǎn)生隨機(jī)的波動
  int rand =(int)
  (System.currentTimeMillis()%777);
  if(rand%2 ==0){
  currentStatus++;
  }else{
  currentStatus--;
  }
  // 將數(shù)據(jù)寫入流中
  dos.writeInt(currentStatus);
  // 在產(chǎn)生更多的隨機(jī)數(shù)時睡眠一會兒
  Thread.sleep(rand/3);
  }
  }}
  
  下面是一個圖表閱讀器組件的簡短代碼示例:
  
  import org.mr.api.blocks.MantaInputStream;
  .../*** 以圖表的方式顯示從輸入流中獲取的數(shù)據(jù)
  */public class GraphViewer {// 運行程序
  public static void main(String[] args)
  throws IOException {
  // 初始化程序
  GraphViewer view = new GraphViewer();
  view.init();
  }
  // 程序邏輯
  public void init() throws IOException{
  // 初始化圖表
  InitGraph();
  // 創(chuàng)建 一個企業(yè)級輸入流
  MantaInputStream in =
  new MantaInputStream();
  // 將企業(yè)級輸出流聯(lián)接到一個叫g(shù)raph的主題上
  in.connect("graph",
  MantaOutputStream.TOPIC);
  // 將輸入流包裝到DataOutputStream中,這樣我們可以輕松地讀出整數(shù)
  DataInputStream dis =
  new DataInputStream(in);
  int input =0;
  boolean go = true;
  while(go){
  try{
  //讀數(shù)據(jù)
  input=dis.readInt();
  }catch(IOException e){
  e.printStackTrace();
  go =false;
  }
  // 更新圖表
  updateGraph(input);
  }
  }}
  
  示例顯示了將一個流包裝到另一個流中去的這種能力。正如你在示例中所看到的,一個DataInputStream和一個DataOutputStream被用來以向流中寫入整數(shù)。這個圖表閱讀器示例的完整代碼可以在MantaRay的最新版本的sample目錄下找到。這篇文章簡化了代碼的例子是為了讓它適合這篇文章的長度。
  
  JMS提供了增強(qiáng)的特性,比如選擇器,它們對于有些任務(wù)來說是有用的,但并沒用被企業(yè)級流支持。另外,面向消息提任務(wù)可以使用JMS API來使其變得更簡單。上述例子顯示了一個像這樣的簡單的面向流的任務(wù)如何從使用MantaRay的企業(yè)級InputStream和OutputStream的簡單的面向流的API中獲益的。
  
  結(jié)論
  
  將JMS的能力與流組合在一起是非常強(qiáng)大的。當(dāng)應(yīng)用使用J2EE框架作為通訊架構(gòu)時,可以使用所有流所具有的強(qiáng)大的能力。對于不想與JMS對象打交道的用戶來說,流也是很有用的,雖然他們有時稍顯復(fù)雜和粗笨。
  
  企業(yè)級流是MantaRay的“積木塊”集合的一部分—簡單并且直接的工具簡化了編寫分布式應(yīng)用的過程,并擴(kuò)展了MantaRay為分布式應(yīng)用通訊所提供的能力。

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 博白县| 碌曲县| 万安县| 林周县| 稷山县| 绍兴市| 和田县| 漠河县| 峨眉山市| 井冈山市| 革吉县| 会宁县| 梧州市| 西平县| 耒阳市| 海南省| 醴陵市| 抚宁县| 紫云| 柏乡县| 玉门市| 龙江县| 静乐县| 永川市| 民勤县| 新野县| 南平市| 资兴市| 沾益县| 体育| 加查县| 衡南县| 日喀则市| 高密市| 嘉义县| 金华市| 贵定县| 抚顺市| 雷山县| 澄城县| 康保县|