Java 8 初探 - Base64

更新於 發佈於 閱讀時間約 5 分鐘
此為過去的舊文,2014 年 5 月 11 日初次發表於 logdown。

這次看一個比較小的東西,就是 Java 8終於將 Base64 編解碼器內建到 java.util 套件中了。Base64 雖然會增加實際傳輸資料的長度,但在只用文字的網路協定中傳輸 binary 資料時常常用到 (例如:MIME email),所以一直到 Java 8 才內建確實讓人意外,在 Java 8 之前,需要 Base64 編解碼器,都需要透過第三方函式庫,例如 Apache Commons Codec

還記得之前某個工作內容是當使用者透過瀏覽器上傳 A 檔案到 X 系統時,因某些原故,X 系統不提供檔案儲放的功能,實際上是將該檔案 A 放到另一個有提供檔案內容檢索的 Y 系統;另一個類似的情況是,當使用者透過瀏覽器在 X 系統下載 B 檔案(內容是機器生成的)時,該檔案 B 會放到 Y 系統的另一個資料夾中備查。X 系統與 Y 系統都是標準的 RESTful Web Service,當時,X 和 Y 系統間檔案內容就是先以 Base64 編碼後,以文字的方式夾帶在 JSON 中透過 HTTP 傳輸。當時用的 Base64 編解碼器正是 Apache Commons Codec。

既然 Java 8 內建 Base64 編解碼器,那就來寫點程式試用看看吧!不過個人的習慣,對於從輸入讀取資料放到輸出這種事,喜歡使用 Apache Commons IOIOUils.copy(InputStream, OutputStream) 函式,不過如果沒有使用 Apache Commons IO,也可以自己寫一個,之後就可以不用再寫 while loop 做資料讀取複製的程式了。


有了輔助函式後,就先使用編碼器,將一個 InputStream 的資料用 Base64 編碼器編碼後放到指定的 OutputStream,下例中,encode(InputStream, OutputStream, Base64.Encoder) 函式接受三個參數,第一個是代表資料的來源,第二個是代表編碼後資料的目的地,這兩個蠻容易理解的,那第三個呢?為什麼還要指定編碼器?難道 Base64 編碼有不同種類嗎?是的,Base64 在不同通訊協定中有些變形,所以 Java 8 提供三種 Base64 的編解碼器。

第一種是基本版 (分別用 Base64.getEncoder()Base64.getDecoder() 取得編解碼器),只用 0-9a-zA-Z+/= 字元編碼且內容不換行;第二種針對網址和檔名修改的版本 (用Base64.getUrlEncoder()Base64.getUrlDecoder() 取得編解碼器),由於 +/ 符號在網址中有特殊用途,某些檔案系統也不允許 / 作為檔名,所以第二種用 - (減號) 取代 +,用 _ (底線) 取代/;第三種針對 MIME 調整的版本 (用 Base64.getMimeEncoder()Base64.getMimeDecoder() 取得編解碼器),使用的編碼字元和第一種一樣,但每輸出76個字元會加上一組 \r\n 換行。假設第一種是比較常用的情況,是可以如下例那樣寫一個無第三參數的版本方便使用。


編碼後就可以用解碼器進行解碼的動作,下例中 decode(InputStream, OutputStream, Base64.Decoder) 同樣接受三個參數,第一個參數是待解碼的資料來源,第二個是解碼後的資料目的地,第三個是解碼器。剛提到的三種不同編解碼器是無法混用的,所以使用第一種編碼器編碼的內容一定要用第一種解碼器來進行解碼。同樣,也可以提共一個無第三參數的版本方便使用,接下來的範例程式都可以用同樣的方法提供一個預先使用第一種編解碼器的版本。


有了從 InputStream 讀取資料進行編碼或解碼動作後放到 OutputStream 的函式後,就可以來點不一樣的變形了,例如像下例,可以指定輸入的檔案和輸出的檔案,利用 FileInputStreamFileOutputStream將檔案包裝成串流來使用,這時就可以使用上面提供的 encodedecode 函示來進行編解碼的動作。


當然,很多時候編解碼後的內容並不是要放到檔案中,以剛剛提到的例子,檔案內容會先被編碼,然後當成 JSON 的一部分,這時會希望有類似的程式,將編解碼後的內容當成字串,這時可以用 ByteArrayOutputStream 暫時存放編解碼後的內容,然後使用 toString(String) 將結果以字串輸出。


同樣,需要被編解碼的資料來源不一定是從檔案來,可能就是個字串,這時下面的函式就幫得上忙了,先用 getBytes() 取得字串的位元組陣列,接著用 ByteArrayInputStream 將位元組陣列包裝成輸入串流,然後用同樣的方法,對輸入的字串進行編解碼的動作。


Java 8 有了 Base64 編解碼器,方便不少,不過 Apache Commons Codec 提供更多常用的編解碼器,其實是更方便的,但如果你的應用程式中只需要 Base64 編解碼器,在有 Java 8 的環境中確實不需要將 Apache Commons Codec 和專案一起打包,對~前提是要有 Java 8 的環境,變成用不用內建的 Base64 編解碼器又是一種抉擇了。

留言
avatar-img
留言分享你的想法!
avatar-img
Spirit的沙龍
54會員
107內容數
這是從 Medium 開始的一個專題,主要是想用輕鬆閒談的方式,分享這幾年軟體開發的心得,原本比較侷限於軟體架構,但這幾年的文章不僅限於架構,也聊不少流程相關的心得,所以趁換平台,順勢換成閒談軟體設計。
Spirit的沙龍的其他內容
2024/05/23
本書大多數的內容都以 OO 的概念出發,詳列了許多設計的臭味道,也有大量的例子。個人雖然不會這樣寫程式,但仍是覺得受益良多,至少在 code review 時能更清楚知道該怎麼描述問題。不過,即便不是用 OO 的概念,有些章節還是可以帶來一些想法,用 OO 概念寫程式的人更不該錯過這本好書。
Thumbnail
2024/05/23
本書大多數的內容都以 OO 的概念出發,詳列了許多設計的臭味道,也有大量的例子。個人雖然不會這樣寫程式,但仍是覺得受益良多,至少在 code review 時能更清楚知道該怎麼描述問題。不過,即便不是用 OO 的概念,有些章節還是可以帶來一些想法,用 OO 概念寫程式的人更不該錯過這本好書。
Thumbnail
2024/05/11
實際就業後,會發現收集與分析需求,通常都不是工程師在做,會有另一群人,以非工程的角度收集及分析需求,然後在開發過程中蹦出不同的火花,於是很好奇另一群人的想法是什麼?我不敢說這本書能完全代表另一群人的想法,但確實能夠得到很多有用的思維。推薦給所有的軟體工程師。
Thumbnail
2024/05/11
實際就業後,會發現收集與分析需求,通常都不是工程師在做,會有另一群人,以非工程的角度收集及分析需求,然後在開發過程中蹦出不同的火花,於是很好奇另一群人的想法是什麼?我不敢說這本書能完全代表另一群人的想法,但確實能夠得到很多有用的思維。推薦給所有的軟體工程師。
Thumbnail
2024/05/09
本書介紹了戰略設計、管理領域複雜度、實際應用領域驅動設計等主題。透過對核心子領域、支持子領域、限界上下文等概念的探討,提供了領域驅動設計的相關知識。這篇文章中還涉及了微服務、事件驅動架構和資料網格等相關主題,提供了設計系統和應用領域驅動設計的指導。
Thumbnail
2024/05/09
本書介紹了戰略設計、管理領域複雜度、實際應用領域驅動設計等主題。透過對核心子領域、支持子領域、限界上下文等概念的探討,提供了領域驅動設計的相關知識。這篇文章中還涉及了微服務、事件驅動架構和資料網格等相關主題,提供了設計系統和應用領域驅動設計的指導。
Thumbnail
看更多
你可能也想看
Thumbnail
孩子寫功課時瞇眼?小心近視!這款喜光全光譜TIONE⁺光健康智慧檯燈,獲眼科院長推薦,網路好評不斷!全光譜LED、180cm大照明範圍、5段亮度及色溫調整、350度萬向旋轉,讓孩子學習更舒適、保護眼睛!
Thumbnail
孩子寫功課時瞇眼?小心近視!這款喜光全光譜TIONE⁺光健康智慧檯燈,獲眼科院長推薦,網路好評不斷!全光譜LED、180cm大照明範圍、5段亮度及色溫調整、350度萬向旋轉,讓孩子學習更舒適、保護眼睛!
Thumbnail
創作者營運專員/經理(Operations Specialist/Manager)將負責對平台成長及收入至關重要的 Partnership 夥伴創作者開發及營運。你將發揮對知識與內容變現、影響力變現的精準判斷力,找到你心中的潛力新星或有聲量的中大型創作者加入 vocus。
Thumbnail
創作者營運專員/經理(Operations Specialist/Manager)將負責對平台成長及收入至關重要的 Partnership 夥伴創作者開發及營運。你將發揮對知識與內容變現、影響力變現的精準判斷力,找到你心中的潛力新星或有聲量的中大型創作者加入 vocus。
Thumbnail
此章節旨在介紹Java的基本語法、註解和變數的使用。透過學習,讀者將了解Java程式的基本結構、程式進入點的定義、如何撰寫單行和多行註解,以及如何宣告和初始化變數。
Thumbnail
此章節旨在介紹Java的基本語法、註解和變數的使用。透過學習,讀者將了解Java程式的基本結構、程式進入點的定義、如何撰寫單行和多行註解,以及如何宣告和初始化變數。
Thumbnail
這篇文章的目的是對Java程式設計語言進行介紹,包括它的特性、應用範疇、主要使用者,以及相關的學習資源和常見的庫與框架。此外,它也提供了一些學習Java的渠道,以及與Java相關的其他知識。
Thumbnail
這篇文章的目的是對Java程式設計語言進行介紹,包括它的特性、應用範疇、主要使用者,以及相關的學習資源和常見的庫與框架。此外,它也提供了一些學習Java的渠道,以及與Java相關的其他知識。
Thumbnail
本篇文章講解了字符編碼的基礎知識,包括ASCII, Unicode 和 UTF-8的誕生背景、解決的問題以及轉換方式。瞭解這些知識有助於解決在讀檔案時用錯誤的編碼方式轉換就會出現亂碼等問題。文章內容涉及電腦技術中的字符編碼相關歷史緣由,可幫助讀者解決相關疑問。
Thumbnail
本篇文章講解了字符編碼的基礎知識,包括ASCII, Unicode 和 UTF-8的誕生背景、解決的問題以及轉換方式。瞭解這些知識有助於解決在讀檔案時用錯誤的編碼方式轉換就會出現亂碼等問題。文章內容涉及電腦技術中的字符編碼相關歷史緣由,可幫助讀者解決相關疑問。
Thumbnail
因為最近想嘗試編碼風格,於是就選了一套比較"不嚴格"的輔助工具來摸索。 編輯器 VS CODE 框架 VUE3 打包工具 VITE 編碼風格 Standard 環境 version { "nodejs":"v18.18.0", "npm":"9.8.1" }
Thumbnail
因為最近想嘗試編碼風格,於是就選了一套比較"不嚴格"的輔助工具來摸索。 編輯器 VS CODE 框架 VUE3 打包工具 VITE 編碼風格 Standard 環境 version { "nodejs":"v18.18.0", "npm":"9.8.1" }
Thumbnail
這幾年新出的語言都強打在少寫 code 和提高可讀性,更重要的是能更容易發展出 domain specific language,就這一點 Java 確實有點顯得疲態了。其實文中列的特性大多是一些語法糖衣,但對程式的可讀性和抽象度都能提昇不少,我覺得挺實用也很划算的。
Thumbnail
這幾年新出的語言都強打在少寫 code 和提高可讀性,更重要的是能更容易發展出 domain specific language,就這一點 Java 確實有點顯得疲態了。其實文中列的特性大多是一些語法糖衣,但對程式的可讀性和抽象度都能提昇不少,我覺得挺實用也很划算的。
Thumbnail
Java 8 有了 Base64 編解碼器,方便不少,不過 Apache Commons Codec 提供更多常用的編解碼器,其實是更方便的,但如果你的應用程式中只需要 Base64 編解碼器,在有 Java 8 的環境中確實不需要將 Apache Commons Codec 和專案一起打包。
Thumbnail
Java 8 有了 Base64 編解碼器,方便不少,不過 Apache Commons Codec 提供更多常用的編解碼器,其實是更方便的,但如果你的應用程式中只需要 Base64 編解碼器,在有 Java 8 的環境中確實不需要將 Apache Commons Codec 和專案一起打包。
Thumbnail
default methods 似乎也引起不小的討論,因為 default methods 加上可以實作多個介面,已經有點像 C++ 的多重繼承了,只差在沒辦法繼承成員變數而已,是好是壞就看怎麼使用了。我個人覺得還蠻方便的
Thumbnail
default methods 似乎也引起不小的討論,因為 default methods 加上可以實作多個介面,已經有點像 C++ 的多重繼承了,只差在沒辦法繼承成員變數而已,是好是壞就看怎麼使用了。我個人覺得還蠻方便的
Thumbnail
老實說,看到 Java Sream API 讓我感到相當親切,這應該跟我研究所多年的研究題目是 visual dataflow language 有關,Java Stream API 把迴圈給內化了,每個 operation 的重點是要做什麼,大大提高了程式的抽象化程度和可讀性。
Thumbnail
老實說,看到 Java Sream API 讓我感到相當親切,這應該跟我研究所多年的研究題目是 visual dataflow language 有關,Java Stream API 把迴圈給內化了,每個 operation 的重點是要做什麼,大大提高了程式的抽象化程度和可讀性。
Thumbnail
最後,Java 8 雖然支援 Lambda,但我覺得 Closure 某種程度上還不稱不上是 Java 的第一級居民,我還是比較喜歡寫一些小而易測的 class,而不是使用 Lambda,至於捕捉變數,透過建構子將變數帶入物件也是一種方式。
Thumbnail
最後,Java 8 雖然支援 Lambda,但我覺得 Closure 某種程度上還不稱不上是 Java 的第一級居民,我還是比較喜歡寫一些小而易測的 class,而不是使用 Lambda,至於捕捉變數,透過建構子將變數帶入物件也是一種方式。
Thumbnail
Java 8 終於在 2014 的 3 月 18 日正式釋出了,不過自從用 Objective C 開發 iOS App後,我已經有好一陣子沒碰 Java,期間曾經有短暫寫一點點,但卻沒有時間去用 beta 版的 Java 8,直到最近才又開始玩一下。
Thumbnail
Java 8 終於在 2014 的 3 月 18 日正式釋出了,不過自從用 Objective C 開發 iOS App後,我已經有好一陣子沒碰 Java,期間曾經有短暫寫一點點,但卻沒有時間去用 beta 版的 Java 8,直到最近才又開始玩一下。
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News