<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
PipedInputStream 和 PipedOutputStream 設計用來解決跨執行緒的位元組資料傳輸。它們總是成對出現的,而在使用上,也只能 工作在兩個不同的執行緒上,在一個執行緒裡使用管道輸入和輸出流可能會造成死鎖。網上有很多介紹這兩個存在於 io 包下的 api。卻幾乎 找不到一個寫 PipedInputStream 的使用場景的,所以本文結合實際業務,來聊一聊 PipedInputStream 的應用。
我們知道,輸出流寫資料,輸入流讀資料,PipedInputStream 和 PipedOutputStream 也一樣,在 PipedOutputStream 的內部有一個 PipedInputStream 型別的 sink屬性,用來接收 PipedOutputStream 寫入的位元組資料。
而在 PipedInputStream 內部,定義了一個預設為 1024 大小的位元組陣列 buffer,作為資料傳輸的緩衝區。這樣一來,就變成了 PipedOutputStream 往 buffer 裡寫資料,當寫滿了 buffer 時,便使用 notifyAll() 喚醒讀資料的執行緒可以讀資料了,然後阻塞 1s 後繼續嘗試寫資料。
PipedInputStream 從 buffer 裡讀資料,當資料讀完 buffer 為空時,便 notifyAll() 喚醒寫的執行緒可以寫資料了,然後阻塞 1s 後繼續嘗試讀資料。
PipedOutputStream 端資料寫完後,呼叫 close() 方法,會標記 PipedInputStream 裡的 closedByWriter=true。此時,從 buffer 讀取資料,會返回 -1。標識了資料讀完到達了流的末尾了。
public static void main(String[] args) { try (PipedOutputStream out = new PipedOutputStream(); PipedInputStream in = new PipedInputStream(out)) { new Thread(() -> { try { out.write("hello kl".getBytes(StandardCharsets.UTF_8)); out.close(); } catch (IOException e) { e.printStackTrace(); } }).start(); int receive; while ((receive = in.read()) != -1) { System.err.print((char) receive); } } catch (IOException e) { e.printStackTrace(); } }
上面程式碼演示了,在一個執行緒裡寫資料,然後在 main 執行緒讀資料的場景,完成了跨執行緒的資料傳輸。寫到這裡,都挺乾巴巴的,很多人看了後肯定也不知道它到底能幹啥,有啥作用,繼續往下看。
簡單的理解了原理後,寫了一個簡單的演示 demo,但是 demo 不能說明啥問題,那從一個執行緒傳輸位元組到另一個執行緒到底有啥用呢?博主,簡單的的總結下:通過 java 應用生成檔案,然後需要將檔案上傳到雲端的場景,都可以用管道流。相同的業務場景,在沒了解管道流之前,都是先將檔案寫入到本地磁碟,然後從檔案磁碟讀出來上傳到雲盤。瞭解這個後,可以腦補出很多的業務場景了(真實業務場景,都是博主遇到過的),比如:
之前有一個檔案匯出的功能,但是因為,匯出的檔案比較大,匯出下載完的時間非常長,所以,設計成了,頁面點選匯出後,後臺觸發匯出任務,然後將mysql 中的資料根據匯出條件查詢出來,生成 Excel檔案,然後將檔案上傳到 oss,最後像觸發匯出任務的人的釘釘發一個下載檔案的連結。之前的做法,正如上面所言,先將檔案寫到本地,然後從本地目錄讀出來上傳到 oss,下面演示下管道流一步到位的方式:
public static void main(String[] args) { try (PipedOutputStream out = new PipedOutputStream(); PipedInputStream in = new PipedInputStream(out)) { new Thread(() -> { Listdatabase = new LinkedList<>(); try { //檔案生成 ExcelUtils.getInstance().exportObjects2Excel(database,out); } catch (IOException e) { e.printStackTrace(); } }).start(); //檔案上傳 ossClient.putObject("test","test.xlsx",in); } catch (IOException e) { e.printStackTrace(); } }
此類需求常見於和銀行以及金融機構對接時,要求上報一些 xml 格式的資料,給到指定的 ftp、或是 oss 的某個目錄下,用於對賬。其實從檔案上傳的場景來說,和上面的案例一是一樣。也是我總結的那樣,在記憶體裡生成檔案,然後上傳到雲端,虛擬碼如下:
public static void main(String[] args) { try (PipedOutputStream out = new PipedOutputStream(); PipedInputStream in = new PipedInputStream(out)) { new Thread(() -> { Listdatabase = new LinkedList<>(); try(GZIPOutputStream gzipOut = new GZIPOutputStream(out)) { Marshaller marshaller = JAXBContext.newInstance(Object.class).createMarshaller(); marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); marshaller.marshal(database,gzipOut); } catch (IOException | JAXBException e) { e.printStackTrace(); } }).start(); //檔案上傳 ossClient.putObject("test","test.xml.gz",in); } catch (IOException e) { e.printStackTrace(); } }
總體來說,和案例一沒啥區別,只是案例二多了一步壓縮操作,最終上傳的檔案是一個 gzip 的壓縮包,壓縮包內是 xml 檔案。用這種方式可以大大減少檔案的體積、提升上傳的速度
PipedInputStream 和 PipedOutputStream 設計用來解決跨執行緒的位元組資料傳輸。在實際業務需求中,當需要在記憶體中生成檔案然後上傳到雲端時,請記得使用管道流
以上就是java管道piped輸入流與輸出流應用場景案例分析的詳細內容,更多關於java管道piped輸入流與輸出流應用的資料請關注it145.com其它相關文章!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45