大檔案 JSON 打不開怎麼辦:按體積選對工具
結論:幾十 MB 的 JSON 匯出檔在文字編輯器和線上工具裡經常直接卡死,但解析本身只要幾百毫秒。本文用一份 45MB、50 萬條記錄的樣本實測各環節耗時與記憶體,解釋行數和節點數才是真正的成本,並給出按檔案體積選工具的決策表:線上查看、命令列提取、串流處理與桌面用戶端各管一段。

一個 45MB 的 JSON 檔案,解析只要 249 毫秒;讓你等半分鐘的是渲染它的 500 萬行文字和 350 萬個樹節點。分不清這兩件事,就永遠在怪錯對象。
一、先實測:解析從來不是瓶頸
很多人雙擊一個幾十 MB 的 .json 匯出檔,看到編輯器轉圈幾十秒,第一反應是「JSON 解析太慢了」。實測結論相反。下面是本機(Node 22)跑的一組數據:樣本是 50 萬條記錄、每條 5 個欄位(id、email、active、score、tags),檔案壓縮後 45MB:
| 操作 | 實測結果 |
|---|---|
JSON.parse 全量解析 |
249 ms |
JSON.stringify(data, null, 2) 美化輸出 |
215 ms |
| 美化後的文字 | 71 MB、5,000,001 行 |
| 樹節點總數(記錄 + 欄位) | 約 3,500,001 個 |
| 解析後 Node 行程 RSS | 313 MB(約 7 倍檔案體積) |
解析花了兩百多毫秒就結束了。也就是說,解析器在你鬆開滑鼠之前就已經幹完活了。之後卡住的十幾秒甚至幾分鐘,全部發生在「把結果展示給人看」這一層:文字編輯器要排版 500 萬行、逐行做語法高亮、維護撤銷緩衝區;樹形檢視器要給 350 萬個節點各建一個 DOM 元素——而瀏覽器在十萬節點量級就會明顯吃力,幾十萬直接失去回應。
這個結論指向一個完全不同的修復方向:別和渲染較勁,換一個不做全量渲染的工具。
二、為什麼會卡:行數與節點數才是真成本
檔案體積只是表象,真正壓垮工具的是兩個衍生數字:
- 行數。一個 45MB 的緊湊 JSON 美化後是 500 萬行。編輯器開啟檔案時無論你看到哪一屏,都得先為全文建立行結構、決定高亮狀態、分配緩衝,成本和總行數成正比。
- 節點數。500 萬條記錄 × (1 個物件 + 5 個欄位)就是 350 萬個樹節點。任何「整棵建樹再展示」的檢視器都要為它付出同等的記憶體與時間,和你只展開了一層還是全部展開無關。
由此還能推出兩條反直覺的結論:先美化再看是幫倒忙——美化把 45MB 變成 71MB、行數翻 40 倍,純粹給工具加壓;把檔案 cat 進終端機也是幫倒忙——終端機回滾緩衝區會成為新的瓶頸,想看開頭幾百位元組用 head -c 2000 就夠。
三、按體積選工具:一張決策表
不同體量的檔案,合適的工具完全不同。結合上面的實測和幾家工具站的公開指南(OpenFormatter 給出線上工具 2-5MB 舒適區、PureJSON 給出 500MB 文字解析後 2-4GB 記憶體的量級估計),可以整理成一張決策表:
| 檔案體積 | 首選 | 理由 |
|---|---|---|
| < 2 MB | 任何線上工具 | 開啟即看,/parse 這類樹形查看 + 校驗一步到位 |
| 2 – 20 MB | 本機編輯器(VS Code 等)或瀏覽器本機工具 | 線上工具開始劣化;本機處理不上傳 |
| 20 – 100 MB | 命令列 jq 探查 + 虛擬化樹檢視器 | 編輯器開始卡;jq 秒級提取任意片段 |
| 100 MB – 1 GB | jq --stream / ijson 串流處理 |
常規解析的記憶體按 7 倍檔案體積漲,裝不下就串流 |
| > 1 GB 或持續附加 | 換格式:NDJSON / CSV / Parquet | 單個大陣列必須完整解析才有第一條記錄,格式本身已經不合适 |
本站 [/parse](/parse) 覆蓋第一檔的樹形查看與校驗;更大的檔案建議用 桌面用戶端 在本機開啟,避免把幾十 MB 數據貼進網頁。
四、不開啟檔案,先問它是什麼結構
拿到一個陌生的大 JSON,第一件事不是開啟,而是花幾秒鐘摸清結構——用 jq 在 200ms 內回答三個問題:
# 頂層是陣列還是物件?多少條記錄?
jq 'if type == "array" then {type: "array", count: length} else {type: "object", keys: (keys|length)} end' huge.json
# 第一條記錄長什麼樣(只看一條,不刷屏)?
jq '.[0]' huge.json | head -40
# 全部欄位名稱(從第一條記錄取)
jq '.[0] | keys' huge.json
知道結構之後,絕大多數需求就變成「提取某個欄位」,根本不需要開啟檔案。比如只要每個使用者的信箱:
jq -r '.[].email' huge.json | less
# 過濾條件再疊加
jq -r '.[] | select(.active == true) | .email' huge.json
規則很簡單:要「看」就找虛擬化渲染的檢視器,要「找」和「取」就用 jq,兩者別混。
五、記憶體的陡坡:普通模式與串流差 150 倍
同一份 45MB 樣本,用 /usr/bin/time -v 實測 jq 兩種模式的記憶體峰值:
| 模式 | 命令 | 記憶體峰值(RSS) | 耗時 |
|---|---|---|---|
| 普通模式(全量載入) | jq '.[0].email' sample.json |
542 MB | 0.7 s |
| 串流模式 | jq --stream 'select(.[0][1]=="email") | .[1]' sample.json |
3.6 MB | 2.5 s |
普通模式把整個檔案讀進記憶體再建物件圖,542MB 峰值正好印證「物件圖 ≈ 7-12 倍文字體積」的量級;--stream 逐個 token 消費輸入,記憶體恆定在個位數 MB,代價是總時間慢一些。檔案到了 GB 級,這個差別就是「能跑」和「直接被 OOM 殺掉」的差別:
# 超過記憶體的檔案:--stream 是唯一不載入全量的方式
jq --stream -n 'fromstream(1|truncate_stream(inputs))' huge.json
Python 側的等價物是 ijson:ijson.items(f, 'item') 逐條產出陣列元素,同樣常數記憶體。這些工具的共同點是放棄了隨機存取——串流只能從頭到尾過一遍,要第二次就得再過一遍。
六、瀏覽器裡能看多大:本機處理的邊界
線上工具不是不能用,而是有邊界。現代瀏覽器單分頁記憶體上限大致 1-4GB,一個 45MB 檔案解析成物件圖加樹渲染,通常還能撐住;到了幾百 MB 就接近懸崖。選線上工具時認準三點:
- 處理在本機完成(貼上內容不發往伺服器),既保護數據也省上傳時間——本站所有工具都是純前端實現,離線也能用;
- 解析放 Web Worker,主執行緒不凍結,卡了還能關掉分頁而不是整個瀏覽器;
- 樹是虛擬化或懶展開的,摺疊的分支幾乎零成本,展開多少渲染多少。
以本站為例:[/parse](/parse) 的樹形查看適合幾十 MB 以內的檔案定位結構,配合錯誤行列定位排查語法;再大的檔案交給 jq 或桌面端,瀏覽器只負責小片段的確認。
七、格式選對了,問題少一半
如果你能影響檔案的產生方,與其換更強的檢視器,不如讓它別長成「一個巨大的陣列」:
- NDJSON/JSONL:一行一條記錄,附加寫入不重寫全檔案,
head、grep、tail、split全套文字工具直接可用;檔案被截斷只損失最後一行。本站 JSONL 手冊裡有完整的壞行排錯流程。 - 分頁匯出:10 萬條記錄的 API 回應應該支援分頁參數,一次 100 條,對雙方都友好。
- 表形數據別用 JSON:一行一條、欄位固定沒有巢狀的數據,本質是表格,CSV 或 Parquet 更省空間、生態也更強。
實測裡有個可以記住的數字:把一個 50 萬條的陣列從中間截斷,前一半依然是一個合法的 NDJSON 檔案(丟一半記錄),而對應的單個大陣列則整個作廢——501 條只恢復出 500 條,總比 0 條強。
八、檢查清單
- 先用
jq '.[0] | keys'或抽樣 500 條摸清結構,再決定怎麼處理; - 不要先美化再開啟——行數翻倍只會更卡;
- 2MB 以下線上樹形查看,20MB 以上命令列,1GB 級一律
--stream或 ijson; - 確認線上工具是本機處理(貼上內容不出瀏覽器);
- 能改產生方就切 NDJSON 或分頁,從源頭消滅巨型單陣列。
常見問題
為什麼編輯器開啟 JSON 要幾十秒,程式裡解析卻只要 200 多毫秒?
解析是原生程式碼把文字變成資料結構,45MB 樣本實測 249ms。編輯器卡在展示層:500 萬行文字要排版、高亮、建撤銷緩衝;樹形檢視要為 350 萬個節點建 DOM。換虛擬化渲染的檢視器或直接用 jq 提取即可繞開。
jq 處理 1GB 以上的 JSON 檔案會溢位嗎?
普通模式會——它把整個文件載入記憶體,物件圖峰值約是檔案的 7-12 倍。加 --stream 後逐 token 消費輸入,實測 45MB 檔案記憶體峰值 3.6MB,檔案多大記憶體都不漲,代價是只能順序遍歷一遍。
線上 JSON 工具最多能看多大的檔案?
多數線上工具的舒適區在 2-5MB,10MB 以上明顯劣化。硬上限取決於瀏覽器分頁記憶體(約 1-4GB),但幾十 MB 時解析加建樹的等待已經很痛苦。超過 20MB 建議換本機工具或命令列。
大 JSON 檔案怎麼只看某個欄位的值?
用 jq 提取,不要開啟全文:jq -r '.[].email' huge.json 輸出所有 email;加過濾 jq -r '.[] | select(.active == true) | .email'。要看前幾條用 jq '.[0:5]' huge.json,比開啟檔案快幾個數量級。
先美化再開啟檔案有幫助嗎?
沒有。美化把緊湊的 45MB 變成 71MB、行數從 1 行變 500 萬行,給編輯器和檢視器增加的都是純負擔。只有最終要給人讀、且檔案不大的情況下才值得美化。