-
1 # 404err
-
2 # 半葉子
剛才研究了一下,確實出現了記憶體溢位情況。
這裡有個小想法,不知可行不可行。
首先先將檔案進行分段,
之後將不同的段進行生成base64編碼,
等全部生成完畢之後,進行base64編碼合併。
-
3 # 都市心聲
說實話,第一眼看到這個問題,我被震住了,心想到底是什麼樣的勇氣能讓題主竟然用base64編碼來處理大檔案,這豈不自尋煩惱,所以對於這個問題,我的建議不是該如何解決base64編碼的大小問題,而是要換一種方式來儲存檔案,比如用檔案系統。
問題剖析先來分析下這個問題的原因,一般搞開發的都知道base64編碼很大程度上是簡化了我們傳輸檔案的方式,特別是對於沒有檔案系統的團隊來說,更是難得,但是這裡的檔案僅僅指的是小檔案、小圖片(如:頭像、二維碼等)之類的,因為大檔案轉化出來的base64編碼真的很長很長,先說這不利於網路傳輸,就算勉強傳輸過去了,資料庫也不見得能儲存下來,就算勉強儲存下來了,重新再獲取的時候也一定會影響速度和效率。
至於題主說的71M的問題,其實base64編碼出來的長度可能就不止71M了,因為base64要求把每三個8Bit的位元組轉換為四個6Bit的位元組(3*8 = 4*6 = 24),然後把6Bit再添兩位高位0,組成四個8Bit的位元組,也就是說,轉換後的字串理論上將要比原來的長1/3,對此,我特意線上編碼了一個大於71M的檔案,感覺還是可以編碼的,只是速度是真的很慢,網頁都卡死了好幾回,不知道題主用的是哪門語言,可能不同語言間也會有差距。
解決方法1、採用檔案系統
對於大檔案的儲存我還是提倡用檔案系統來進行儲存,這樣的話就只要儲存檔案路徑就好了,這樣不僅傳輸快,資料庫各方面也沒啥壓力,讀寫檔案也很方便。
可能有的團隊覺得搭建檔案系統很麻煩,並且也沒有多餘的伺服器來管理檔案,如果是這樣的話,其實還可以考慮用雲端的檔案系統(如:阿里雲OSS),這樣的話,我們儲存檔案的時候就只要用它們介面將檔案傳給雲端,獲取檔案的時候就只要調特定的介面獲取檔案url即可。2、將大檔案切割成小檔案
如果仍然是不想用檔案系統的話,那就只好從源頭出發,把大檔案切割成小檔案,然後依次用base64編碼,還原的時候就先將base64編碼轉成對應的小檔案, 然後不同的小檔案再合成大檔案。
切割的方式可以透過壓縮檔案的方式,比如對一個31M的檔案右擊 -> 新增到壓縮檔案,下面會有一個分卷的地方,大小可以填小一點,如下圖所示:
然後點“確定”後就會生成3個小檔案,如下圖所示:
合成檔案就更簡單了,將這三個小檔案右擊 -> 解壓到當前目錄或某一個目錄下就好了。
這種方法雖然也能達到目的,但是也看到了,這樣處理檔案的代價是非常大的。
結束語base64編碼雖然是個好東西,從一定程度上簡化了開發人員處理小檔案的方式,但是卻不是通用的,所以我們在處理小檔案上可以採用base64編解碼的方式,但是對於大檔案來說還是建議使用檔案系統的方式,這樣不僅對檔案的管理更得體,也可以減少開發中遇到的不少問題。
-
4 # shawn25
base64只是一種二進位制轉換字元的編碼方式而已,並不存在什麼位數限制。這多大的資料都能編碼,這是毫無疑問的。
所以你編碼71M檔案時出錯,很明顯是你使用的轉換庫有問題。
這個報錯很明顯是這個庫編碼base64時,直接把輸出的base64編碼存到了一個字串變數裡去,導致字串變數資料過大,從而益出報錯。
所以解決方案很簡單,不要直接去對71M的資料進行轉換。
一 你可以在讀取圖片的時候,不要一次性把圖片全部載入到記憶體裡,而是寫一個迴圈,按照固定的位數去讀區。絕大多數語言的read()方法都支援位讀取。
這樣一塊一塊的編碼就不會溢位了。
二 你也可以使用緩衝區而不是變數,先把圖片讀到緩衝區中,然後同上,按照位數分片轉換。
最後要注意,輸出結果的時候,千萬不能把結果直接累加在一個變數中,這樣一樣會溢位。
你可以
一 分片轉換,然後分片直接列印
二 分片的把結果寫入一個檔案中
三 直接分片進行網路傳輸,客戶端在進行組合。
四 用陣列,堆,字典等等複雜資料結構來儲存結果。
-
5 # WuShilin
不評價為何需要這麼大的base64,第一,base64是編碼方式並不存在71兆的限制
第二,如果你遇到的庫有這個限制,可能是實現的方式,或者你呼叫了簡版的API,肯定是可以流式處理的。
-
6 # 藍鳥啃蘋果
明白了估計是想用base64過防火牆傳送檔案,其實我建議還是切片方式最理想
比如按照1MB為一個緩衝區把byte[]讀取出來做base64編碼傳遞後再合併是最高效率的,另外可以檢視一下網路的mtu對資料包做調整,這樣可以提高檔案切片的傳輸效率。
另外base64可以用opencl提高編碼和解碼速度
-
7 # BlueIce41582507
base64只是一個常見的編碼手段,沒有容量的限制。我猜是你用的類庫有問題,或者自己的程式碼有問題。以資料流的方式處理,是不存在任何限制的。
想起來以前計算md5,一開始不懂,就是把整個檔案讀到記憶體裡再計算,經常發生記憶體溢位。後來仔細看文件,發現還有個方法,可以分段計算。
補充:剛注意到你用的是certutil ,這個本來是用來處理證書的,證書本身都很小,所以它沒提過流式處理也正常。
我們經常說“殺雞用宰牛刀”,你這算是“宰牛用殺雞刀”了。
回覆列表
Base64是網路上最常見的用於傳輸8Bit位元組程式碼的編碼方式之一,Base64編碼可用於在HTTP環境下傳遞較長的標識資訊。
採用Base64編碼具有不可讀性,即所編碼的資料不會被人用肉眼所直接看到。(經過編碼,人們肯定直接看不懂)
在MIME格式的電子郵件中,base64可以用來將binary的位元組序列資料編碼成ASCII字元序列構成的文字。
使用時,在傳輸編碼方式中指定base64。使用的字元包括大小寫字母各26個,加上10個數字,和加號“+”,斜槓“/”,一共64個字元,等號“=”用來作為字尾用途。
Base64編碼要求把3個8位位元組(38=24)轉化為4個6位的位元組(46=24),之後在6位的前面補兩個0,形成8位一個位元組的形式。
如果剩下的字元不足3個位元組,則用0填充,輸出字元使用"=",因此編碼後輸出的文字末尾可能會出現1或2個"="。
為了保證所輸出的編碼位可讀字元,Base64制定了一個編碼表,以便進行統一轉換。編碼表的大小為2^6=64,這也是Base64名稱的由來。