① 數據流詳細資料大全
數據流(data stream)是一組有序,有起點和終點的位元組的數據序列。包括輸入流和輸出流。
數據流最初是通信領域使用的概念,代表傳輸中所使用的信息的數字編碼信號序列。這個概念最初在1998年由Henzinger在文獻87中提出,他將數據流定義為「只能以事先規定好的順序被讀取一次的數據的一個序列」。
基本介紹
- 中文名 :數據流
- 外文名 :data stream
- 概念提出人 :Henzinger
- 提出時間 :1998年
- 釋義 :以規定順序被讀取一次的數據序列
- 發展原因 :2個
- 數據模式 :4個
- 計算類型 :可分為兩類:基本計算和復雜計算
產生背景,細節數據,復雜分析,區別特徵,分類,輸入流與輸出流,緩沖流,模型描述,形式化,數據集合,數據屬性,計算類型,相關思路,簡介,隨機采樣,構造略圖,直方圖,小波變換,新動向,小說流派,
產生背景
數據流套用的產生的發展是以下兩個因素的結果:
細節數據
已經能夠持續自動產生大量的細節數據。這類數據最早出現於傳統的銀行和股票交易領域,後來則也出現為地質測量、氣象首悉尺、天文觀測等方面。尤其是網際網路(網路流量監控,點擊流)和無線通信網(通話記錄)的出現,產生了大量的數據流類型的數據。我們注意到這類數據大都與地理信息有一定關聯,這主要是因為地理信息的維度較大,容易產生這類大量的細節數據。
復雜分析
需要以近實時的方式對更新流進行復雜分析。對以上領域的數據進行復雜分析(如趨勢分析,預測)以前往往是(在數據倉庫中)離線進行的,然而一些新的套用(尤其是在網路安全和國家安全領域)對時間都非常敏感,如檢測網際網路上的極端事件、欺詐、入侵、異常,復雜人群監控,趨勢監控(track trend),探查性分析(exploratory *** yses),和諧度分析(harmonic *** ysis)等,都需要進行在線上的分析。 在此之後,學術界基本認可了這個定義,有的文章也在此基礎上對定義稍微進行了修改。例如,S. Guha等[88]認為,數據流是「只能被讀取一次或少數幾次的點的有序序列」,這里放寬了前述定義中的「一遍」限制。 為什麼在數據流的處理中,強調對數據讀取次數的限制呢?S. Muthukrishnan[89]指出數據流是指「以非常高的速者高度到來的輸入數據」,因此對數據流數據的傳輸、計算和存儲都將變得很困難。在這種情況下,只有在數據最初到達時有機會對其進行一次處理,其他時候很難再存取到這些數據(因為沒有也無法保存這些數據)。
區別特徵
與傳統的關系數據模式區別 B.Babcock等[90]認為數據流模式在以下幾個方面不同於傳統的關系數據模式: 1. 數據在線上到達; 2. 處理
系統無法控制所處理的數據的到達順序; 3. 數據可能是無限多的; 4. 由於數據量的龐大,數據流中的元素被處理後將被拋棄或存檔(archive)。以後再想獲取這些數據將會很困難,除非將數據存儲在記憶體中,但由於記憶體大小通常遠遠小於數據流數據的數量,因此實際上通常只能在數據第一次到達時獲取數據。
三個 特點 我們認為,當前所研究的數據流計算之所以不同於傳統的計算模式,關鍵在於這些數據流數據本身具有如下三個陸襲特點:
數據的到達—快速 這意味著短時間內可能會有大量的輸入數據需要處理。這對處理器和輸入輸出設備來說都是一個較大的負擔,因此對數據流的處理應盡可能簡單。
酷睿2處理器 數據的范圍—廣域 這是指數據屬性(維)的取值范圍非常大,可能取的值非常多,如地域、手機號碼、人、網路節點等。這才是導致數據流無法在記憶體或硬碟中存儲的主要原因。如果維度小,即使到來的數據量很大,也可以在較小的存儲器中保存這些數據。例如,對於無線通信網來說,同樣的100萬條通話記錄,如果只有1000個用戶,那麼使用1000個存儲單位就可以保存足夠多和足夠精確的數據來回答「某一用戶的累計通話時間有多長」的問題;而如果共有100000個用戶,要保存這些信息,就需要100000個存儲單位。數據流數據的屬性大多與地理信息、IP位址、手機號碼等有關,而且往往與時間聯系在一起。這時,數據的維度遠遠超過了記憶體和硬碟容量,這意味著系統無法完整保存這些信息,通常只能在數據到達的時候存取數據一次。
數據到達的時間—持續 數據的持續到達意味著數據量可能是無限的。而且,對數據進行處理的結果不會是最終的結果,因為數據還會不斷地到達。因此,對數據流的查詢的結果往往不是一次性而是持續的,即隨著底層數據的到達而不斷返回最新的結果。 以上數據流的特點決定了數據流處理的特點一次存取,持續處理,有限存儲, 近似結果,快速回響。 近似結果是在前三個條件限制下產生的必然結果。由於只能存取數據一次,而且只有相對較小的有限空間存儲數據,因此產生精確的計算結果通常是不可能的。而將對結果的要求從過去的「精確」改為「近似」後,實現數據流查詢的快速回響也就成為了可能。
分類
數據的性質、格式不同,則對流的處理方法也不同,因此,在
java的輸入/輸出類庫中,有不同的流類來對應不同性質的輸入/輸出流。在java.io包中,基本輸入/輸出流類可按其讀寫數據的類型之不同分為兩種:位元組流和字元流。
輸入流與輸出流
數據流分為輸入流(InputStream)和輸出流(OutputStream)兩類。輸入流只能讀不能寫,而輸出流只能寫不能讀。通常程式中使用輸入流讀出數據,輸出流寫入數據,就好像數據流入到程式並從程式中流出。採用數據流使程式的輸入輸出操作獨立與相關設備。 輸入流可從鍵盤或檔案中獲得數據,輸出流可向顯示器、印表機或檔案中傳輸數據。
緩沖流
為了提高數據的傳輸效率,通常使用緩沖流(Buffered Stream),即為一個流配有一個緩沖區(buffer),一個緩沖區就是專門用於傳輸數據的記憶體塊。當向一個緩沖流寫入數據時,系統不直接傳送到外部設備,而是將數據傳送到緩沖區。緩沖區自動記錄數據,當緩沖區滿時,系統將數據全部傳送到相應的設備。 當從一個緩沖流中讀取數據時,系統實際是從緩沖區中讀取數據。當緩沖區空時,系統就會從相關設備自動讀取數據,並讀取盡可能多的數據充滿緩沖區。
模型描述
我們試圖從數據集合、數據屬性和計算類型三個不同方面對數據流的模型進行歸納和描述。實際上,很多文章提出了各種各樣的數據流模型,我們並沒有包括所有這些模型,只是將其中比較重要的和常見的進行了歸納和分類。
形式化
以下是對數據流的一個形式化描述。 考慮向量α,其屬性的域為[1..n](秩為n),而且向量α在時間t的狀態 α(t)=<α1(t), ...αi(t), ...αn(t) > 在時刻s,α是0向量,即對於所有i,αi(s)=0。對向量的各個分量的更新是以二元組流的形式出現的。即,第t個更新為(i, ct),意味著αi(t)= αi(t . 1) + ct,且對於i. =.i,αi. (t)= αi. (t . 1)。在時刻t發生的查詢是針對α(t)的。
數據集合
我們首先考慮在進行數據流計算時,有哪些數據被包含在計算范圍之內。關於這個問題,主要有三種不同的模型:分別是數據流模型(data stream model)、滑動視窗模型(sliding window model)和n-of-N模型。 數據流模型(data stream model)在數據流模型中,從某個特定時間開始的所有數據都要被納入計算范圍。此時,s=0,即在時刻0,α是0向量。即這是數據流最初和最普遍的模型。 滑動視窗模型(sliding window model ,計算最近的N個數據)滑動視窗模型是指,從計算時算起,向前追溯的N個數據要被納入計算范圍。此時,s = t . N,即在時刻t . N,α是0向量。換句話說,要計算最近的N個數據。由於數據流的數據是不斷涌現的,所以直觀的看,這種模式就像用一個不變的視窗,數據隨時間的推移經過視窗,出現視窗內的數據就是被計算的數據集合。M. Datar等[91]首先提出這一模式,隨後得到了廣泛回響[92]。 n-of-N模型(計算最近的n個數據,其中0 <n ≤ N) 文獻[93] 提出的這種模型建立在滑動視窗模型的基礎之上,比滑動視窗模型更為靈活:被納入計算范圍的是從計算時算起,向前追溯的n個數據。此時,s = t . n,即在時刻t . n,α是0向量。注意,其中n ≤ N,而且是可以隨查詢要求變化的。而在滑動視窗模型中,n = N而且是固定不變的。對於數據流處理系統來說,要能夠回答所有長度小於等於N的滑動視窗問題。
數據屬性
數據本身的特徵: 時間序列(time series model) 數據按照其屬性(實際上就是時間)的順序前來。在這種情況下,i = t,即一個t時刻的更新為(t, ct)。此時對α的更新操作為αt(t)= ct, 且對於i. =.t,αi. (t)= αi. (t . 1)。這種模型適用於時序數據,如某特定IP的傳出的數據,或股票的定期更新數據等。 收款機模型(cash register model) 同一屬性的數據相加,數據為正。在這種模型中,ct >=0。這意味著對於所有的i和t來說,αi(t)總是不小於零,而且是遞增的。實際上,這種模型被認為是最常用的,例如可以用於對收款機(收款機模型由此得名),各個IP的網路傳輸量,手機用戶的通話時長的監控等等。 十字轉門模型(turnstile model) 同一屬性的數據相加,數據為正或負。在這種模型中,ct可以大於0也可以小於0。這是最通用的模型。S. Muthukrishnan[89]稱其為十字轉門模型起因於這種模型的功能就象捷運站的十字轉門,可以用來計算有多少人到達和離開,從而得出捷運中的人數。
計算類型
對數據流數據的計算可以分為兩類:基本計算和復雜計算。基本計算主要包括對點查詢、范圍查詢和內積查詢這三種查詢的計算。復雜計算包括對分位數的計算、頻繁項的計算以及數據挖掘等。 點查詢(Point query) 返回αi(t)的值。 范圍查詢(Range query) 對於范圍查詢Q(f, t),返回 t . αi(t) i=f 內積(Inner proct) 對於向量β,α與β的內積 α . β =Σni=1αi(t)βi 分位數(Quantile) 給定一個序號r,返回值v,並確保v在α中的真實排序r.符合以下要求: r . εN ≤ r. ≤ r + εN 其中,ε是精度,N =Σni=1αi(t)。 G. S. Manku等[94]提供了對分位數進行一遍掃描進行近似估計的框架結構,將數據集合看成樹的節點,這些節點擁有不同的權重(如節點中包含的數據個數)。認為所有的分位數的估計演算法都可以被認為由三個對節點的操作組成產生新節點(NEW) 、合並(COLLAPSE)和輸出(OUTPUT)。不同的策略構成了不同類型的樹。這個框架結構成為後來很多分位數估計演算法的基礎。 頻繁項(Frequent items)有時也稱Heavy hitters,即找出在數據流中頻繁出現的項。在這種計算中,實際上令ct =1。這樣,αi(t)中保存了截至t時刻,維值等於i的數據到達的頻率。對這些數據的查詢又可分為兩種: 找出頭k個最頻繁出現的項 找出所有出現頻率大於1/k的項 對頻率項的研究主要集中在後一種計算[95]。 挖掘對數據流數據進行挖掘涉及更復雜的計算。對這方面的研究包括:多維分析[96],分類分析[97, 98],聚類分析[99–102],以及其他one-pass演算法[103]。
相關思路
簡介
數據流處理過程中的主要難點在於如何將存儲數據所花費的空間控制在一定范圍之內。查詢回響時間問題雖然也很重要,但相對容易解決。作為研究領域的一個熱點,數據流處理問題得到了廣泛的研究,出現了很多演算法。 解決數據流龐大的數據量與有限的存儲空間之間的矛盾的一個思路是使用采樣,另一個思路是,構造一個小的、能提供近似結果的數據結構存放壓縮的數據流數據,這個結構能存放在存儲器中。略圖(Sketch)、直方圖(histogram)和小波(wavelet)實際上就都是這樣的數據結構中最重要的三種。 以上方法實際上大都已用於傳統資料庫領域,問題在於如何將它們套用於數據流的特殊環境。
隨機采樣
隨機采樣(Random sampling)可以通過抽取少量樣本來捕捉數據集合的基本特性。一個很常見的簡單方法就是一致性采樣(uniform sample)。作為一個備選的采樣方法分層采樣(strati.ed sampling)可以減少數據的不均勻分布所帶來的誤差。不過,對於復雜的分析,普通的采樣演算法還是需要太大的空間。 對於數據流的一些特殊計算,已經出現了一些有趣的采樣演算法。粘采樣(Sticky sampling)[95]用於頻繁項(frequent items)的計算。粘采樣使用的方法是,在記憶體中存放二元組(i,f)所構成的集合S,對於每到來的一個數據,如果其鍵i已經存在於S,則對應的f加1;否則,以1 r 的機率進行采樣,如果該項被選中,在S中增加一組(i,1);每過一段時間,對S中的組進行一遍掃描,對其中的值進行更新。然後增加r的值;結束(或用戶要求結果)時,輸出所有f.(s-e)N的組。 P. Gibbons提出的distinct sampling[104]用於distinct counting ,即找出數據流中不同值的個數。它使用哈希(hash )函式對每一個到來的不同值以2.(i+1)的機率映射到級別i上;如果i ≥記憶體級別L(L的初始值為0),將其加入記憶體,否則拋棄;記憶體滿時,將記憶體中級別為L的值刪除,並將L加1;最終對distinct count的估計為記憶體中不同的值乘以2L。distinct counting是資料庫處理中的一個老問題,這種演算法的優點是,通過設定合適的參數,可套用於帶謂詞的查詢(即對數據流的一個子集進行distinct counting)。 采樣演算法的缺點是:它們對異常數據不夠敏感。而且,即使它們可以很好的套用於普通的數據流模型,但如果要用於滑動視窗模型(sliding window model)[91] 或n-of-N模型[93],還需要進行較大的修改。
構造略圖
構造略圖(sketching)是指使用隨機映射(Random projections)將數據流投射在一個小的存儲空間內作為整個數據流的概要,這個小空間存儲的概要數據稱為略圖,可用於近似回答特定的查詢。不同的略圖可用於對數據流的不同Lp范數的估算,進而這些Lp范數可用於回答其它類型的查詢。如L0范數可用於估算數據流的不同值(distinct count);L1范數可用於計算分位數(quantile)和頻繁項(frequent items);L2范數可用於估算自連線的長度等等。 略圖的概念最早由N. Alon在[105]中提出,從此不斷涌現出各種略圖及其構造演算法。 N. Alon 在[105]中提出的隨機略圖構造(randomized steching)可以用於對不同Lp范數的估算,最多需要O(n 1. lg n)的空間。該文更重要的貢獻在於,它還可以以O(log n + log t)的空間需求估算L2。它的主要思路是,使用哈希函式,將數據屬性的域D中的每一個元素一致地隨機映射到zi ∈ {.1+ 1}上,令隨機變數X = .i αizi,X2就可作為對L2范數的估計。 p1 S. Guha 等[88]提出的分位數略圖(quantile sketch) 保持一組形如(vi,gi, Δi)的數據結構,rmax(vi) 和rmin(vi)分別是vi可能的排位的最大和最小值。對於i>j 滿足: vi >vj gi = rmin(vi) . rmin(vi . 1) Δi = rmax(vi) . rmin(vi) 隨著數據的到來,對此略圖進行相應的更新操作,使估算保持在一定的精度之內。X. Lin等[93]對於這個問題做出了更形式化的描述。 若令AS為一個從[1..n]中提取的隨機集合,每一個元素被提取的機率為1/2。A. Gilbert 等[106]構造若干個AS,將每個集合中元素值的和稱為隨機和(random sum)。多個隨機和構成一個略圖。對αi的估算為 2E(||AS|| |αi ∈ AS) . ||A||, 其中||A||為數據流中所有數的和。因此,這種略圖可用於估算點查詢的結果。使用多個這樣的略圖,可用於估算范圍查詢、分位數查詢等。略圖技術實際上是空間和精度相權衡的結果。為保證點查詢結果的誤差小於εN, 上述略圖需要的空間通常是以ε.2作為系數的。與此相比較,G. Cormode 等提出的計數-最小略圖(Count-Min Sketch )[19]只需要ε.1系數的空間。其思路也比較簡單,使用若干個哈希函式將分別數據流投射到多個小的略圖上,回答點查詢時,每個略圖分別作答,並選擇值最小的作為答案。以點查詢為基礎,計數-最小略圖可以用於其它各種查詢和復雜計算。計數-最小略圖並不計算Lp范數,而是直接計算出點查詢的結果,這是它的時空效率比其它略圖高的原因之一。
直方圖
直方圖(histogram)有兩個含義:一個是普通意義上的直方圖,是一種用於顯示近似統計的視覺手段;另外,它還是一種捕捉數據的近似分布的數據結構/方法。作為後者出現時時,直方圖是這樣構造的:將數據按其屬性分到多個不相交的子集(稱為桶)並用某種統一的方式近似表示桶中的值[107]。
直方圖 直方圖方法主要用於信號處理、統計、圖像處理、計算機視覺和資料庫。在資料庫領域,直方圖原先主要用於選擇性估計(selectivity estimation),用於選擇查詢最佳化和近似查詢處理。直方圖是一種最簡單、最靈活的近似處理方法,同時也是最有效的一種。只要解決好數據更新問題,就可以將原有的直方圖運用到數據流處理中。這類根據新的數據自動調節的直方圖被稱為動態(或自適應/自調節)直方圖。 L. Fu等[108]提出的直方圖主要用於中值函式(Median )和其他分位數函式的計算,可用於近似計算,也可用於精確查詢。它通過確定性分桶(Deterministic Bucketing )和隨機分桶(Randomized Bucketing )技術,構造多個不同精度的桶(buckets),然後將輸入數據逐級分到這些桶中,從而完成了動態直方圖的構造。 由於將靜態直方圖直接套用到數據流處理比較困難。S. Guha等[88]雖然可以動態地構造近最優的V-optimal 直方圖,但只能套用於時間序列模型(time series model) 下的數據流。 一個常採用的方法是將整個演算法分為兩步:首先構造一個數據流數據的略圖;然後從這個略圖中構造合適的直方圖。這種方法可以利用略圖數據易於更新的特點,又能實現直方圖的動態化。N. Thaper等[109]首先是構造一個近似反映數據流數據的略圖,利用略圖的優良的更新性能來實現數據的更新,然後從這個略圖中導出一個直方圖來實現對數據流數據的近似。由於從略圖中導出最佳的直方圖是一個NP-hard問題,作者提供了一個啟發式演算法(貪婪演算法)來搜尋一個較佳的直方圖。 A. Gilbert等[110]構造了一個概要的數據結構,該結構使用一組與文獻[106]中類似的隨機和結構來保存不同粒度級別的dyadic interval的值。隨後,將不同粒度級別的dyadic interval([111])從大到小地加入所要構造的直方圖中,這樣就將近似誤差降到最低(求精)。 A. Gilbert等在文獻[112]中主要考慮的是如何降低對數據流中每個輸入數據的處理復雜度。他們先將輸入數據轉化為小波系數(利用小波系數是信號與基向量的內積),然後採用了與文獻[110]類似的dyadic interval處理方法。略圖與直方圖有很密切的聯系,從某種方面來說,可以認為直方圖是略圖的一種特殊情況。
小波變換
小波變換(wavelet transformation)常用於生成數據的概要信息。這是因為通常小波系數只有很少一部分是重要的,大部分系數或者值很小,或者本身不重要。所以,如果忽略數據經過小波變換後生成的不重要系數,就可以使用很少的空間完成對原數據的近似。 Y. Matias等首先針對數據流數據構造一個直方圖,使用小波對其進行模擬。隨後保留若干最重要的小波系數實現對直方圖的模擬。當新的數據出現時,通過對這些小波系數進行更新以實現直方圖的更新。 文獻提出的實際上是一種直方圖方法,只不過使用了小波變換。A. Gilbert等指出小波變換可以認為是信號與一組正交的長度為N的向量集合所作的內積,因此構造一組數據流數據的略圖,由於略圖可以相當容易和准確地計算信號與一組向量的內積,則可以從略圖計算出小波系數,從而用於點查詢和范圍查詢的估計。
新動向
研究人員對數據流處理的研究不斷深入,我們認為出現了以下新的動向:
未來略圖 引入更多多的的統計 計技技術來構造略圖 G. Cormode等主要處理對頻繁項的計算。它以前人的主項(majority item ) 演算法([116, 117])為基礎,使用了error-correcting codes來處理問題。如數據的每一位設立一個計數器,再根據這些計數器的計數結果來推斷頻繁項集合。 Y. Tao等[118]實質上是對Probabilistic counting (已經廣泛地用於資料庫領域的distinct counting)在數據流處理的一種套用。
擴展略圖 對略圖進行擴展,以處理更更復復雜的查詢詢需需求 Lin等在文獻[93]中構造了一個復雜的略圖體系,可用於滑動視窗模型(sliding window model )和n-of-N模型的分位數估計,這是簡單略圖難以做到的。 在滑動視窗模型下,文獻[93]將數據按時間順序分為多個桶,在每個桶中建立略圖(精度比要求的高),然後查詢時再將這些略圖合並(merge),其中對最後一個桶可能需要進行提升(lift )操作。維護時只刪除過期的桶,增加新的桶。 在n-of-N model中,文獻[93]將數據按EH Partitioning技術分為多個大小不同的桶,在每個桶中建立略圖(精度比要求的高),然後查詢時再將其中一部分略圖合並,可以保證要求的精度,其中對最後一個同可能需要進行提升。
結合時空數據 與時空數據處理的進一步結合: J. Sun等在文獻[120]中雖然主要針對時空數據的歷史查詢和預測處理。然而,文章卻強調時空數據是以數據流的形式出現的,處理中也更著重於時空數據的更新性能。 Y. Tao等[118]使用數據流的方法處理時空數據,通過對動態的時空數據構造略圖,用於分辨物體是否在多個區域間運動或靜止的狀態,並估算其數量。而這種問題在原先的時空處理中是很難解決的。
小說流派
網路小說數據流是新興流派,意思是小說主角實力數據化,和網游屬性欄一樣的數據顯示。
② 數據流的分類
數據的性質、格式不同,則對流的處理方法也不同,因此,在Java的輸入/輸出類庫中,有不同的流類來對應不同性質的輸入/輸出流。在java.io包中,基本輸入/輸出流類可按其讀寫數據的類型之不同分為兩種:位元組流和字元流。 數據流分為輸入流(InputStream)和輸出流(OutputStream)兩類。輸入流只能讀不能寫,而輸出流只能寫不能讀。通常程序中使用輸入流讀出數據,輸出流寫入數據,就好像數據流入到程序並從程序中流出。採用數據流使程序的輸入輸出操作獨立與相關設備。
輸入流可從鍵盤或文件中獲得數據,輸出流可向顯示器、列印機或文件中傳輸數據。 為了提高數據的傳輸效率,通常使用緩沖流(Buffered Stream),即為一個流配有一個緩沖區(buffer),一個緩沖區就是專門用於傳輸數據的內存塊。當向一個緩沖流寫入數據時,系統不直接發送到外部設備,而是將數據發送到緩沖區。緩沖區自動記錄數據,當緩沖區滿時,系統將數據全部發送到相應的設備。
當從一個緩沖流中讀取數據時,系統實際是從緩沖區中讀取數據。當緩沖區空時,系統就會從相關設備自動讀取數據,並讀取盡可能多的數據充滿緩沖區。
③ java 流的分類有哪些
按流向分:
輸入流來: 程序可以從中讀取源數據的流。
輸出流: 程序能向其中寫入數據的流。
按數據傳輸單位分:
位元組流: 以位元組為單位傳輸數據的流
字元流: 以字元為單位傳輸數據的流
按功能分:
節點流: 用於直接操作目標設備的流
④ Java中流的分類都有哪些
位元組流類
抽象父類: InputStream,OutputStream
實現類包括如下幾種:
BufferedInputStream 緩沖流-過慮流
BufferedOutputStream
ByteArrayInputStream 位元組數組流-節點流
ByteArrayOutputStream
DataInputStream 處理JAVA標准數據流-過慮流
DataOutputStream
FileInputStream 處理文件IO流-節點流
FileOutputStream
FilterInputStream 實現過慮流-位元組過慮流父類
FilterOutputStream
PipedInputStream 管道流
PipedOutputStream
PrintStream 包含print() 和 println()
RandomAccessFile 支持隨機文件
字元流
抽象父類:Reader, Writer
⑤ java 輸入輸出流 (被採納為答案者加100分)
stream代表的是任何有能力產出數據的數據源,或是任何有能力接收數據的接收源。在Java的IO中,所有的stream(包括Inputstream和Out stream)都包括兩種類型:
(1)位元組流
表示以位元組為單位從stream中讀取或往stream中寫入信息,即io包中的inputstream類和outputstream類的派生類。通常用來讀取二進制數據,如圖象和聲音。
(2)字元流
以Unicode字元為導向的stream,表示以Unicode字元為單位從stream中讀取或往stream中寫入信息。
區別:
Reader和Writer要解決的,最主要的問題就是國際化。原先的I/O類庫只支持8位的位元組流,因此不可能很好地處理16位的Unicode字元流。Unicode是國際化的字元集(更何況Java內置的char就是16位的Unicode字元),這樣加了Reader和Writer之後,所有的I/O就都支持Unicode了。此外新類庫的性能也比舊的好。
但是,Read和Write並不是取代InputStream和OutputStream,有時,你還必須同時使用"基於byte的類"和"基於字元的類"。為此,它還提供了兩個"適配器(adapter)"類。InputStreamReader負責將InputStream轉化成Reader,而OutputStreamWriter則將OutputStream轉化成Writer。
一.流的層次結構
定義:
(1) java將讀取數據對象成為輸入流,能向其寫入的對象叫輸出流。
二.InputStream類
inputstream類和outputstream類都為抽象類,不能創建對象,可以通過子類來實例化。
InputStream是輸入位元組數據用的類,所以InputStream類提供了3種重載的read方法.Inputstream類中的常用方法:
(1) public abstract int read( ):讀取一個byte的數據,返回值是高位補0的int類型值。
(2) public int read(byte b[ ]):讀取b.length個位元組的數據放到b數組中。返回值是讀取的位元組數。該方法實際上是調用下一個方法實現的
(3) public int read(byte b[ ], int off, int len):從輸入流中最多讀取len個位元組的數據,存放到偏移量為off的b數組中。
(4) public int available( ):返回輸入流中可以讀取的位元組數。注意:若輸入阻塞,當前線程將被掛起,如果InputStream對象調用這個方法的話,它只會返回0,這個方法必須由繼承InputStream類的子類對象調用才有用,
(5) public long skip(long n):忽略輸入流中的n個位元組,返回值是實際忽略的位元組數, 跳過一些位元組來讀取
(6) public int close( ) :我們在使用完後,必須對我們打開的流進行關閉.
三.OutputStream類
OutputStream提供了3個write方法來做數據的輸出,這個是和InputStream是相對應的。
1. public void write(byte b[ ]):將參數b中的位元組寫到輸出流。
2. public void write(byte b[ ], int off, int len) :將參數b的從偏移量off開始的len個位元組寫到輸出流。
3. public abstract void write(int b) :先將int轉換為byte類型,把低位元組寫入到輸出流中。
4. public void flush( ) : 將數據緩沖區中數據全部輸出,並清空緩沖區。
5. public void close( ) : 關閉輸出流並釋放與流相關的系統資源。
注意:
1. 上述各方法都有可能引起異常。
2. InputStream和OutputStream都是抽象類,不能創建這種類型的對象。
四.FileInputStream類
FileInputStream類是InputStream類的子類,用來處理以文件作為數據輸入源的數據流。使用方法:
方式1:
File fin=new File("d:/abc.txt");
FileInputStream in=new FileInputStream(fin);
方式2:
FileInputStream in=new
FileInputStream("d: /abc.txt");
方式3:
構造函數將 FileDescriptor()對象作為其參數。
FileDescriptor() fd=new FileDescriptor();
FileInputStream f2=new FileInputStream(fd);
五.FileOutputStream類
FileOutputStream類用來處理以文件作為數據輸出目的數據流;一個表示文件名的字元串,也可以是File或FileDescriptor對象。
創建一個文件流對象有兩種方法:
方式1:
File f=new File("d:/abc.txt");
FileOutputStream out=new FileOutputStream (f);
方式2:
FileOutputStream out=new
FileOutputStream("d:/abc.txt");
方式3:構造函數將 FileDescriptor()對象作為其參數。
FileDescriptor() fd=new FileDescriptor();
FileOutputStream f2=new FileOutputStream(fd);
方式4:構造函數將文件名作為其第一參數,將布爾值作為第二參數。
FileOutputStream f=new FileOutputStream("d:/abc.txt",true);
注意:
(1)文件中寫數據時,若文件已經存在,則覆蓋存在的文件;(2)的讀/寫操作結束時,應調用close方法關閉流。
舉例:2-1
六.File類
File類與InputStream / OutputStream類同屬於一個包,它不允許訪問文件內容。
File類主要用於命名文件、查詢文件屬性和處理文件目錄。
舉例:2-2
七.從一個流構造另一個流
java的流類提供了結構化方法,如,底層流和高層過濾流。
而高層流不是從輸入設備讀取,而是從其他流讀取。同樣高層輸出流也不是寫入輸出設備,而是寫入其他流。
使用"分層對象(layered objects)",為單個對象動態地,透明地添加功能的做法,被稱為Decorator Pattern。Decorator模式要求所有包覆在原始對象之外的對象,都必須具有與之完全相同的介面。這使得decorator的用法變得非常的透明--無論對象是否被decorate過,傳給它的消息總是相同的。這也是Java I/O類庫要有"filter(過濾器)"類的原因:抽象的"filter"類是所有decorator的基類。Decorator模式常用於如下的情形:如果用繼承來解決各種需求的話,類的數量會多到不切實際的地步。Java的I/O類庫需要提供很多功能的組合,於是decorator模式就有了用武之地。
為InputStream和OutputStream定義decorator類介面的類,分別是FilterInputStream和FilterOutputStream。
7.1 FilterInputStream
.......
具體去這里看看把,有很詳細的介紹。希望對你有幫助。
⑥ java.io的Java流輸入輸出原理
Java把這些不同來源和目標的數據都統一抽象為數據流。Java語言的輸入輸出功能是十分強大而靈活的,美中不足的是看上去輸入輸出的代碼並不是很簡潔,因為你往往需要包裝許多不同的對象。
在Java類庫中,IO部分的內容是很龐大的,因為它涉及的領域很廣泛:標准輸入輸出,文件的操作,網路上的數據流,字元串流,對象流,zip文件流。 按流向分:
輸入流: 程序可以從中讀取數據的流。
輸出流: 程序能向其中寫入數據的流。
按數據傳輸單位分:
位元組流: 以位元組為單位傳輸數據的流
字元流: 以字元為單位傳輸數據的流
按功能分:
節點流: 用於直接操作目標設備的流
過濾流: 是對一個已存在的流的鏈接和封裝,通過對數據進行處理為程序提供功能強大、靈活的讀寫功能。 JDK所提供的所有流類位於java.io包中,都分別繼承自以下四種抽象流類。
InputStream:繼承自InputStream的流都是用於向程序中輸入數據的,且數據單位都是位元組(8位)。
OutputStream:繼承自OutputStream的流都是程序用於向外輸出數據的,且數據單位都是位元組(8位)。
Reader:繼承自Reader的流都是用於向程序中輸入數據的,且數據單位都是字元(16位)。
Writer:繼承自Writer的流都是程序用於向外輸出數據的,且數據單位都是字元(16位)。 BufferedInputStream BufferedInputStream 為另一個輸入流添加一些功能,即緩沖輸入以及支持 mark 和 reset 方法的能力。 BufferedOutputStream 該類實現緩沖的輸出流。 BufferedReader 從字元輸入流中讀取文本,緩沖各個字元,從而實現字元、數組和行的高效讀取。 BufferedWriter 將文本寫入字元輸出流,緩沖各個字元,從而提供單個字元、數組和字元串的高效寫入。 ByteArrayInputStream ByteArrayInputStream 包含一個內部緩沖區,該緩沖區包含從流中讀取的位元組。 ByteArrayOutputStream 此類實現了一個輸出流,其中的數據被寫入一個 byte 數組。 CharArrayReader 此類實現一個可用作字元輸入流的字元緩沖區。 CharArrayWriter 此類實現一個可用作 Writer 的字元緩沖區。 Console 此類包含多個方法,可訪問與當前 Java 虛擬機關聯的基於字元的控制台設備(如果有)。 DataInputStream 數據輸入流允許應用程序以與機器無關方式從底層輸入流中讀取基本 Java 數據類型。 DataOutputStream 數據輸出流允許應用程序以適當方式將基本 Java 數據類型寫入輸出流中。 File 文件和目錄路徑名的抽象表示形式。 FileDescriptor 文件描述符類的實例用作與基礎機器有關的某種結構的不透明句柄,該結構表示開放文件、開放套接字或者位元組的另一個源或接收者。 FileInputStream FileInputStream 從文件系統中的某個文件中獲得輸入位元組。 FileOutputStream 文件輸出流是用於將數據寫入 File 或 FileDescriptor 的輸出流。 FilePermission 此類表示對文件和目錄的訪問。 FileReader 用來讀取字元文件的便捷類。 FileWriter 用來寫入字元文件的便捷類。 FilterInputStream FilterInputStream 包含其他一些輸入流,它將這些流用作其基本數據源,它可以直接傳輸數據或提供一些額外的功能。 FilterOutputStream 此類是過濾輸出流的所有類的超類。 FilterReader 用於讀取已過濾的字元流的抽象類。 FilterWriter 用於寫入已過濾的字元流的抽象類。 InputStream 此抽象類是表示位元組輸入流的所有類的超類。 InputStreamReader InputStreamReader 是位元組流通向字元流的橋梁:它使用指定的 charset 讀取位元組並將其解碼為字元。 LineNumberInputStream 已過時。此類錯誤假定位元組能充分表示字元。