首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> J2ME

J2ME Pak 文件格式設計與實現:資源打包加密一站式解決方案

     編輯:J2ME

為什麼需要 Pak 文件

  • JAR 大小限制(早期機型 64KB/128KB/300KB)
  • ZIP/JAR 對大量小文件壓縮率低於單一大文件
  • 資源保護:防止圖片/音頻/腳本被直接提取
  • 讀取性能:單文件連續讀取優於大量小文件隨機訪問

Pak 文件格式規範

文件頭

字段類型長度說明
Signaturechar[]6 字節魔數標識,如 "PAK001"
Versionfloat4 字節格式版本
FileTableCountint4 字節包含文件數
CipherActionbyte1 字節0=加法,1=減法
CipherValuebyte1 字節加密鍵值
UniqueIDchar[]10 字節文件唯一標識
Reservedint4 字節保留擴展

文件表項

字段類型長度說明
FileNamechar[]30 字節文件名,不足補空
FileSizeint4 字節原始文件大小
Offsetint4 字節在 Pak 中偏移量

數據區

按文件表順序拼接的加密後文件二進制數據。

核心類設計

PakHeader / PakFileTable

純數據持有類,提供 size() 靜態方法計算結構體大小,支援序列化/反序列化。

PakUtil (J2SE 版) —— 製作端

  • makePakFile(String[] srcPaths, String destPath, PakHeader header):掃描源文件→構建文件表→寫入頭/表/加密數據
  • extractFileFromPak(...):解析頭/表→定位偏移→讀取解密→輸出文件或字節數組
  • showPakFileInfo(...):列表 Pak 內容
  • 加密:簡單字節加減法(b ± key),J2ME 端解密極快

PakUtil (J2ME 版) —— 運行時讀取端

  • 僅保留只讀功能:解析頭/表、定位偏移、讀取解密、返回 byte[]
  • 通過 getClass().getResourceAsStream("/res/data.pak") 讀取 JAR 內資源
  • 返回字節數組可直接用 Image.createImage(bytes, 0, len) 生成圖片
  • 無文件系統依賴,純 MIDP 1.0 兼容

關鍵實現細節

偏移量計算

// 文件數據區起始偏移
long dataStart = PakHeader.size() + header.getFileTableCount() * PakFileTable.size();

// 第 i 個文件偏移
offset[i] = dataStart + sum_{j< i} fileSize[j];

加密/解密對稱性

// 加密 (J2SE)
if (action == ADD) b += key; else b -= key;

// 解密 (J2ME/J2SE)
if (action == ADD) b -= key; else b += key;

使用流程

  1. 開發機運行 J2SE PakUtil,將 res/*.png 打包為 data.pak
  2. 將 data.pak 放入 J2ME 專案 /res 目錄
  3. J2ME 運行時:PakUtil.extractResourceFromPak("/res/data.pak", "hero.png") 獲取字節數組
  4. Image.createImage(bytes, 0, bytes.length) 直接渲染

優缺點與改進方向

優點缺點/改進
極簡依賴,無第三方庫加密強度低,建議升級為 XOR/RC4/AES
J2ME 端零臨時文件,內存友好不支援壓縮,可引入 LZ77/Deflate
隨機讀取 O(1) 定位文件名長度固定 30 字節,可改為長度前綴
支援任意二進制資源無目錄結構,可擴展路徑分隔符

總結

Pak 方案以最小代價解決了 J2ME 時代的資源體積、保護、讀取三大痛點。其「預製打包 + 運行時隨機讀取」的架構思想,在現代遊戲引擎的 AssetBundle/Pak 系統中依然延續。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved