序言:
由于前些时间,一些matrixer常问关于j2me中使用pak文件的问题。本人虽学艺不深,但满怀热心的做了一番探索,现将制作pak文件的看法和方法公布出来,大家多多提意见。
一、什么是pak文件:
pak文件就是将多个文件打包为一个单独文件,在这个文件中保存着多个文件的数据,当然还有一些描述文件结构的数据。所以将“pak”作为文件的后缀是一种常规的用法,大家可以自定义其它的文件后缀。
二、为什么使用pak文件:
由于midp对发布安装的j2me程序大小进行了限制,所以缩小发布程序就意味着能够提供更多的程序或者内容(如图片、音乐)给用户。而通过研究发现zip/jar算法对大文件的压缩率高于对等量的多个小文件的压缩率。
当然还有其它方法,这里简单做一下讨论比如使用混淆器proguard的“-overloadaggressively”选项使jar文件缩小,但也会导致一些错误,因为这种方法生成jar中的class符合java byte code标准,但是与java语法相悖,严重的可能造成一些jre对object的序列化错误。
所以使用pak方法将程序中要用到的资源(图片、音乐、文本)组合为单一文件是一个安全有效的方法。而且对于一些商用程序,完全可以在pak文件中对文件数据进行加密,很好的保护了作者和公司的权益。本人的sample中使用了简单的“加减法”加密,对于手机这类设备来讲是一个效率较高的选择。
三、pak文件的结构:
大家可以自己设计pak文件结构,本人这里只是抛砖引玉的作个sample。下面就是本人设计的pak文件结构:
pak file header:pak文件的头部
* 签名:6字节char数组 * 版本号:32位float * 文件table数量:32位整数 * 密码行为:8位字节 * 密码:8位字节 * 文件唯一id:10字节char数组 * 保留位:32位整数(4字节)
file table:pak文件中包含文件的列表,在一个pak文件中一个被包含的文件对应一个file table。
* 文件名:30字节char数组 * 文件大小:32位整型 * 文件在pak文件中的位移:32位整数
concatenated file data:按file table的顺序连接在一起的文件数据。
* 文件数据
四、程序框架:
说明:由于pak文件的制作和使用分别要使用两个java应用领域:j2se和j2me,所以本人将pakutil类制作了2个版本(j2se和j2me)。
程序框架如下:
1。pakheader类,定义了pak文件头。
2。pakfiletable类,定义pak文件table。
3。pakutil类(j2se版),具备两个功能:将多个png图片合成一个pak文件,并使用简单的加减加密法对其进行加密;从pak文件中取出png图片,构造byte数组(可以用来构造image对象)或者写为文件。
pakutil类(j2me版),具备的功能:从pak文件中取出png图片,构造byte数组(可以用来构造image对象)。
五、pakheader和pakfiletable类:
pakheader.java:
package cn.org.matrix.gmatrix.gamelab.util.pak;/** * pak文件头: * 结构: *
签名:6字节char数组 * 版本号:32位float *
文件table数量:32位整数 *
密码行为:8位字节 * 密码:8位字节 *
文件唯一id:10字节char数组 *
保留位:32位整数(4字节) * @author cleverpig * */class pakheader {
//定义文件唯一id长度
public static final int uniqueid_length=10;
//定义文件签名长度
public static final int signature_length=6;
//定义加法运算
public static final int addition_cipheraction=0;
//定义减法运算
public static final int subtract_cihoeraction=1;
//文件签名
private char[] signature=new char[signature_length];
//版本号
private float version=0f;
//文件table数量
private long numfiletableentries=0;
//密码使用方法:在原数据上进行加法还是减法
private byte cipheraction=addition_cipheraction;
//密码值
private byte ciphervalue=0x00;
//唯一id
private char[] uniqueid=new char[uniqueid_length];
//保留的4字节
private long reserved=0;
public pakheader(){
}
/**
* 构造方法
* @param signature 签名
* @param version 版本
* @param numfiletableentries 文件table数量
* @param cipheraction 密码使用方法
* @param ciphervalue 密码值
* @param uniqueid 唯一id
* @param reserved 保留的2字节
*/
public pakheader(char[] signature,float version,
long numfiletableentries,byte cipheraction,
byte ciphervalue,char[] uniqueid,long reserved){
for(int i=0;i<signature_length;this.signature[i]=signature[i],i++)
;
this.version=version;
this.cipheraction=cipheraction;
this.numfiletableentries=numfiletableentries;
this.ciphervalue=ciphervalue;
for(int i=0;i<uniqueid_length;this.uniqueid[i]=uniqueid[i],i++);
this.reserved=reserved;
}
public byte getciphervalue() {
return ciphervalue;
}
public void setciphervalue(byte ciphervalue) {
this.ciphervalue = ciphervalue;
}
public long getnumfiletableentries() {
return numfiletableentries;
}
public void setnumfiletableentries(long numfiletableentries) {
this.numfiletableentries = numfiletableentries;
}
public long getreserved() {
return reserved;
}
public void setreserved(long reserved) {
this.reserved = reserved;
}
public char[] getuniqueid() {
return uniqueid;
}
public void setuniqueid(char[] uniqueid) {
for(int i=0;i<uniqueid_length;this.uniqueid[i]=uniqueid[i],i++)
;
}
public float getversion() {
return version;
}
public void setversion(float version) {
this.version = version;
}
public byte getcipheraction() {
return cipheraction;
}
public void setcipheraction(byte cipheraction) {
this.cipheraction = cipheraction;
}
public char[] getsignature() {
return signature;
}
public void setsignature(char[] signature) {
for(int i=0;i<signature_length;this.signature[i] = signature[i],i++)
;
}
/**
* 返回pakheader的大小
* @return 返回pakheader的大小
*/
public static int size(){
return signature_length+4+4+1+1+uniqueid_length+4;
}
public string tostring(){
string result="";
result+="/t签名:"+new string(this.signature).trim()
+"/t版本号:"+this.version
+"/t文件table数量:"+this.numfiletableentries
+"/t密码行为:" +this.cipheraction
+"/t密码:"+this.ciphervalue
+"/t文件唯一id:"+new string(this.uniqueid).trim() +"/t保留位:"+this.reserved;
return result;
}}
pakfiletable.java
package cn.org.matrix.gmatrix.gamelab.util.pak;/** * pak文件table类 * 文件table结构: *
文件名:30字节char数组 *
文件大小:32位整型 *
文件在pak文件中的位移:32位整数 * @author cleverpig * */class pakfiletable {
public static final int filename_length=30;
//文件名
private char[] filename=new char[filename_length];
//文件大小
private long filesize=0l;
//文件在pak文件中的位移
private long offset=0l;
public pakfiletable(){
}
/**
* 构造方法
* @param filename 文件名
* @param filesize 文件大小
* @param offset 文件在pak文件中的位移
*/
public pakfiletable(char[] filename,
long filesize,long offset){
for(int i=0;i<filename_length;this.filename[i]=filename[i],i++)
; this.filesize=filesize;
this.offset=offset;
}
public char[] getfilename() {
return filename;
}
public void setfilename(char[] filename) {
for(int i=0;i<filename.length;this.filename[i]=filename[i],i++)
;
}
public long getfilesize() {
return filesize;
}
public void setfilesize(long filesize) {
this.filesize = filesize;
}
public long getoffset() {
return offset;
}
public void setoffset(long offset) {
this.offset = offset;
}
/**
* 返回文件table的大小
* @return 返回文件table的大小
*/
public static int size(){
return filename_length+4+4;
}
public string tostring(){
return "/t文件名:"+new string(this.filename).trim()
+"/t文件大小:"+this.filesize
+"/t文件位移:"+this.offset;
}}
六、pakutil类(j2se版):
pakutil.java
package cn.org.matrix.gmatrix.gamelab.util.pak;import java.io.*;
import java.util.vector;
/** * pak工具类 * 功能:
*1.将多个png图片合成一个pak文件,并使用简单的加减加密法对其进行加密;
* 2.从pak文件中取出png图片,构造byte数组(可以用来构造image对象)或者写为文件 * @author cleverpig * */public class pakutil {
public pakutil(){
}
/**
* 返回文件长度
* @param filepath 文件路径
* @return 文件长度
*/
private long getfilesize(string filepath){
file file=new file(filepath);
return file.length();
}
/**
* 返回文件名
* @param filepath 文件路径
* @return 文件名
*/
private string getfilename(string filepath){
file file=new file(filepath);
return file.getname();
}
/**
* 计算文件位移的起始点
* @return 文件位移的起始点
*/
private long workoutoffsetstart(pakheader header){
//计算出文件头+文件table的长度
return pakheader.size()+header.getnumfiletableentries()*pakfiletable.size();
}
/**
* 计算文件位移
* @param fileindex 文件序号
* @param lastfileoffset 上一个文件位移
* @return 文件在pak文件中的位移
*/
private long workoutnextoffset(long sourcefilesize,long lastfileoffset){
return lastfileoffset+sourcefilesize;
}
/**
* 生成文件table
* @param sourcefilename 源文件名
* @param sourcefilesize 源文件长度
* @param currentfileoffset 当前文件位移
* @return 生成的pakfiletable对象
*/
private pakfiletable generatefiletable(string sourcefilename,
long sourcefilesize,long currentfileoffset){
pakfiletable ft=new pakfiletable();
ft.setfilename(sourcefilename.tochararray());
ft.setfilesize(sourcefilesize);
ft.setoffset(currentfileoffset);
return ft;
}
/**
* 将char字符数组写入到dataoutputstream中
* @param towritechararray 被写入的char数组
* @param dos dataoutputstream
* @throws exception
*/
private void writechararray(char[] towritechararray,dataoutputstream dos) throws exception{
for(int i=0;i<towritechararray.length;dos.writechar(towritechararray[i]),i++);
}
/**
* 使用文件头中的密码对数据进行加密
* @param buff 被加密的数据
* @param bufflength 数据的长度
* @param header 文件头
*/
private void encryptbuff(byte[] buff,int bufflength,pakheader header){
for(int i=0;i<bufflength;i++){
switch(header.getcipheraction()){
case pakheader.addition_cipheraction:
buff[i]+=header.getciphervalue();
break;
case pakheader.subtract_cihoeraction:
buff[i]-=header.getciphervalue();
break;
}
}
}
/**
* 使用文件头中的密码对数据进行解密
* @param buff 被解密的数据
* @param bufflength 数据的长度
* @param header 文件头
*/
private void decryptbuff(byte[] buff,int bufflength,pakheader header){
for(int i=0;i<bufflength;i++){
switch(header.getcipheraction()){
case pakheader.addition_cipheraction:
buff[i]-=header.getciphervalue();
break;
case pakheader.subtract_cihoeraction:
buff[i]+=header.getciphervalue();
break;
}
}
}
/**
* 制作pak文件
* @param sourcefilepath 源文件路径数组
* @param destinatefilepath 目的文件路径(pak文件)
* @param cipheraction 密码行为
* @param ciphervalue 密码
* @throws exception
*/
public void makepakfile(string[] sourcefilepath,
string destinatefilepath,pakheader header) throws exception{
pakfiletable[] filetable=new pakfiletable[sourcefilepath.length];
//计算文件位移起始点
long fileoffset=workoutoffsetstart(header);
//逐个建立文件table
for(int i=0;i<sourcefilepath.length;i++){
string sourcefilename=getfilename(sourcefilepath[i]);
long sourcefilesize=getfilesize(sourcefilepath[i]);
pakfiletable ft=generatefiletable(sourcefilename,sourcefilesize,fileoffset);
//计算下一个文件位移
fileoffset=workoutnextoffset(sourcefilesize,fileoffset);
filetable[i]=ft;
}
//写入文件头
file wfile=new file(destinatefilepath);
fileoutputstream fos=new fileoutputstream(wfile);
dataoutputstream dos=new dataoutputstream(fos);
writechararray(header.getsignature(),dos);
dos.writefloat(header.getversion());
dos.writelong(header.getnumfiletableentries());
dos.writebyte(header.getcipheraction());
dos.writebyte(header.getciphervalue());
writechararray(header.getuniqueid(),dos);
dos.writelong(header.getreserved());
//写入文件table
for(int i=0;i<filetable.length;i++){
writechararray(filetable[i].getfilename(),dos);
dos.writelong(filetable[i].getfilesize());
dos.writelong(filetable[i].getoffset());
}
//写入文件数据
for(int i=0;i<filetable.length;i++){
file ftfile=new file(sourcefilepath[i]);
fileinputstream ftfis=new fileinputstream(ftfile);
datainputstream ftdis=new datainputstream(ftfis);
byte[] buff=new byte[256];
int readlength=0;
while((readlength=ftdis.read(buff))!=-1){
encryptbuff(buff,readlength,header);
dos.write(buff,0,readlength);
}
ftdis.close();
ftfis.close();
}
dos.close();
}
/**
* 从datainputstream读取char数组 * @param dis datainputstream
* @param readlength 读取长度
* @return char数组
* @throws exception
*/
private char[] readchararray(datainputstream dis,int readlength) throws exception{
char[] readchararray=new char[readlength];
for(int i=0;i<readlength;i++){
readchararray[i]=dis.readchar();
}
return readchararray;
}
/**
* 从pak文件中读取文件头
* @param dis datainputstream
* @return pakheader
* @throws exception
*/
private pakheader readheader(datainputstream dis) throws exception{
pakheader header=new pakheader();
char[] signature=readchararray(dis,pakheader.signature_length);
header.setsignature(signature);
header.setversion(dis.readfloat());
header.setnumfiletableentries(dis.readlong());
header.setcipheraction(dis.readbyte());
header.setciphervalue(dis.readbyte());
char[] uniqueid=readchararray(dis,pakheader.uniqueid_length);
header.setuniqueid(uniqueid);
header.setreserved(dis.readlong());
return header;
}
/**
* 读取所有的文件table
* @param dis datainputstream
* @param filetablenumber 文件表总数
* @return 文件table数组
* @throws exception
*/
private pakfiletable[] readfiletable(datainputstream dis,int filetablenumber) throws exception{
pakfiletable[] filetable=new pakfiletable[filetablenumber];
for(int i=0;i<filetablenumber;i++){
pakfiletable ft=new pakfiletable();
ft.setfilename(readchararray(dis,pakfiletable.filename_length));
ft.setfilesize(dis.readlong());
ft.setoffset(dis.readlong());
filetable[i]=ft;
}
return filetable;
}
/**
* 从pak文件读取文件到byte数组
* @param dis datainputstream
* @param filetable pakfiletable
* @return byte数组
* @throws exception
*/
private byte[] readfilefrompak(datainputstream dis,pakheader header,pakfiletable filetable) throws exception{
dis.skip(filetable.getoffset()-workoutoffsetstart(header));
//
int filelength=(int)filetable.getfilesize();
byte[] filebuff=new byte[filelength];
int readlength=dis.read(filebuff,0,filelength);
if (readlength<filelength){
system.out.println("读取数据长度不正确");
return null;
}
else{
decryptbuff(filebuff,readlength,header);
return filebuff;
}
}
/**
* 将buffer中的内容写入到文件
* @param filebuff 保存文件内容的buffer
* @param filename 文件名
* @param extractdir 文件导出目录
* @throws exception
*/
private void writefilefrombytebuffer(byte[] filebuff,string filename,string extractdir) throws exception{
string extractfilepath=extractdir+filename;
file wfile=new file(extractfilepath);
fileoutputstream fos=new fileoutputstream(wfile);
dataoutputstream dos=new dataoutputstream(fos);
dos.write(filebuff);
dos.close();
fos.close();
}
/**
* 从pak文件中取出指定的文件到byte数组,如果需要的话可以将byte数组写为文件
* @param pakfilepath pak文件路径
* @param extractfilename pak文件中将要被取出的文件名
* @param writefile 是否需要将byte数组写为文件
* @param extractdir 如果需要的话可以将byte数组写为文件,extractdir为取出数据被写的目录文件
* @return byte数组
* @throws exception
*/
public byte[] extractfilefrompak(string pakfilepath,
string extractfilename,boolean writefile,string extractdir) throws exception{
file rfile=new file(pakfilepath);
fileinputstream fis=new fileinputstream(rfile);
datainputstream dis=new datainputstream(fis);
pakheader header=readheader(dis);
pakfiletable[] filetable=readfiletable(dis,(int)header.getnumfiletableentries());
boolean find=false; int fileindex=0;
for(int i=0;i<filetable.length;i++){
string filename=new string(filetable[i].getfilename()).trim();
if (filename.equals(extractfilename)){
find=true;
fileindex=i;
break;
}
}
if (find==false){
system.out.println("没有找到指定的文件");
return null;
}
else{
byte[] buff=readfilefrompak(dis,header,filetable[fileindex]);
if (writefile){
writefilefrombytebuffer(buff,extractfilename,extractdir);
}
else{
dis.close();
fis.close();
}
return buff;
}
}
/**
* 从pak文件中取出指定的pak文件的信息
* @param pakfilepath pak文件路径
* @return 装载文件头和文件table数组的vector
* @throws exception
*/
public vector showpakfileinfo(string pakfilepath) throws exception{
file rfile=new file(pakfilepath);
fileinputstream fis=new fileinputstream(rfile);
datainputstream dis=new datainputstream(fis);
pakheader header=readheader(dis);
pakfiletable[] filetable=readfiletable(dis,(int)header.getnumfiletableentries()); vector result=new vector();
result.add(header);
result.add(filetable);
return result;
}
public static void main(string[] argv) throws exception{
pakutil pu=new pakutil();
//构造文件头
char[] signature=new char[pakheader.signature_length];
signature=new string("012345").tochararray();
char[] uniqueid=new char[pakheader.uniqueid_length];
uniqueid=new string("0123456789").tochararray();
pakheader header=new pakheader();
header.setsignature(signature);
header.setnumfiletableentries(3);
header.setcipheraction((byte)pakheader.addition_cipheraction);
header.setciphervalue((byte)0x0f);
header.setuniqueid(uniqueid);
header.setversion(1.0f);
header.setreserved(0l);
string[] filepatharray={"f://eclipse3.1rc3//workspace//gmatrixproject_j2se//testfiles//apple.png",
"f://eclipse3.1rc3//workspace//gmatrixproject_j2se//testfiles//cushaw.png",
"f://eclipse3.1rc3//workspace//gmatrixproject_j2se//testfiles//flash.png"};
string extractfilepath="f://eclipse3.1rc3//workspace//gmatrixproject_j2se//testfiles//test.pak";
//制作pak文件
system.out.println("制作pak文件...");
pu.makepakfile(filepatharray,extractfilepath,header);
system.out.println("制作pak文件完成");
//从pak文件中取出所有的图片文件
vector pakinfo=pu.showpakfileinfo(extractfilepath);
header=(pakheader)pakinfo.elementat(0);
system.out.println("pak文件信息:");
system.out.println("文件头:");
system.out.println(header);
pakfiletable[] filetable=(pakfiletable[])pakinfo.elementat(1);
for(int i=0;i<filetable.length;i++){
system.out.println("文件table["+i+"]:");
system.out.println(filetable[i]);
}
string restoredir="f://eclipse3.1rc3//workspace//gmatrixproject_j2se//testfiles//extract//";
string restorefilename=null;
byte[] filebuff=null;
for(int i=0;i<filetable.length;i++){
restorefilename=new string(filetable[i].getfilename()).trim();
system.out.println("从pak文件中取出"+restorefilename+"文件...");
filebuff=pu.extractfilefrompak(extractfilepath,restorefilename,true,restoredir);
system.out.println("从pak文件中取出"+restorefilename+"文件保存在"+restoredir+"目录");
}
}}
七、pakutil类(j2me版):
pakutil.java
package cn.org.matrix.gmatrix.gamelab.util.pak;
import java.io.*;
import java.util.vector;
/** * pak工具类 * 功能: * 从pak文件中取出png图片,构造byte数组(可以用来构造image对象) * @author cleverpig * */public class pakutil {
public pakutil(){
}
/**
* 计算文件位移的起始点
* @return 文件位移的起始点
*/
private long workoutoffsetstart(pakheader header){
//计算出文件头+文件table的长度
return pakheader.size()+header.getnumfiletableentries()*pakfiletable.size();
}
/**
* 从datainputstream读取char数组
* @param dis datainputstream
* @param readlength 读取长度
* @return char数组
* @throws exception
*/
private char[] readchararray(datainputstream dis,int readlength) throws exception{
char[] readchararray=new char[readlength];
for(int i=0;i<readlength;i++){
readchararray[i]=dis.readchar();
}
return readchararray;
}
/**
* 从pak文件中读取文件头
* @param dis datainputstream
* @return pakheader
* @throws exception
*/
private pakheader readheader(datainputstream dis) throws exception{
pakheader header=new pakheader();
char[] signature=readchararray(dis,pakheader.signature_length);
header.setsignature(signature);
header.setversion(dis.readfloat());
header.setnumfiletableentries(dis.readlong());
header.setcipheraction(dis.readbyte());
header.setciphervalue(dis.readbyte());
char[] uniqueid=readchararray(dis,pakheader.uniqueid_length);
header.setuniqueid(uniqueid);
header.setreserved(dis.readlong());
return header;
}
/**
* 读取所有的文件table
* @param dis datainputstream
* @param filetablenumber 文件表总数
* @return 文件table数组
* @throws exception
*/
private pakfiletable[] readfiletable(datainputstream dis,int filetablenumber) throws exception{
pakfiletable[] filetable=new pakfiletable[filetablenumber];
for(int i=0;i<filetablenumber;i++){
pakfiletable ft=new pakfiletable();
ft.setfilename(readchararray(dis,pakfiletable.filename_length));
ft.setfilesize(dis.readlong());
ft.setoffset(dis.readlong());
filetable[i]=ft;
}
return filetable;
}
/**
* 从pak文件读取文件到byte数组
* @param dis datainputstream
* @param filetable pakfiletable
* @return byte数组
* @throws exception
*/
private byte[] readfilefrompak(datainputstream dis,pakheader header,pakfiletable filetable) throws exception{
dis.skip(filetable.getoffset()-workoutoffsetstart(header));
//
int filelength=(int)filetable.getfilesize();
byte[] filebuff=new byte[filelength];
int readlength=dis.read(filebuff,0,filelength);
if (readlength<filelength){
system.out.println("读取数据长度不正确");
return null;
}
else{
decryptbuff(filebuff,readlength,header);
}
return filebuff;
}
/**
* 使用文件头中的密码对数据进行解密
* @param buff 被解密的数据
* @param bufflength 数据的长度
* @param header 文件头
*/
private void decryptbuff(byte[] buff,int bufflength,pakheader header){
for(int i=0;i<bufflength;i++){
switch(header.getcipheraction()){
case pakheader.addition_cipheraction:
buff[i]-=header.getciphervalue();
break;
case pakheader.subtract_cihoeraction:
buff[i]+=header.getciphervalue();
break;
}
}
}
/**
* 从pak文件中取出指定的文件到byte数组
* @param pakresourceurl pak文件的资源路径
* @param extractresourcename pak文件中将要被取出的文件名
* @return byte数组
* @throws exception
*/
public byte[] extractresourcefrompak(string pakresourceurl
,string extractresourcename) throws exception{
inputstream is=this.getclass().getresourceasstream(pakresourceurl);
datainputstream dis=new datainputstream(is);
pakheader header=readheader(dis);//
system.out.println("文件头:");//
system.out.println(header);
pakfiletable[] filetable=readfiletable(dis,(int)header.getnumfiletableentries());//
for(int i=0;i<filetable.length;i++){//
system.out.println("文件table["+i+"]:");//
system.out.println(filetable[i]);//
}
boolean find=false;
int fileindex=0;
for(int i=0;i<filetable.length;i++){
string filename=new string(filetable[i].getfilename()).trim();
if (filename.equals(extractresourcename)){
find=true;
fileindex=i;
break;
}
}
if (find==false){
system.out.println("没有找到指定的文件");
return null;
}
else{
byte[] buff=readfilefrompak(dis,header,filetable[fileindex]);
return buff;
}
}
/**
* 从pak文件中取出指定的pak文件的信息
* @param pakresourcepath pak文件资源路径
* @return 装载文件头和文件table数组的vector
* @throws exception
*/
public vector showpakfileinfo(string pakresourcepath) throws exception{
inputstream is=this.getclass().getresourceasstream(pakresourcepath);
datainputstream dis=new datainputstream(is);
pakheader header=readheader(dis);
pakfiletable[] filetable=readfiletable(dis,(int)header.getnumfiletableentries());
vector result=new vector();
result.addelement(header);
result.addelement(filetable);
return result;
}
public static void main(string[] argv) throws exception{
pakutil pu=new pakutil();
string extractresourcepath="/test.pak";
//从pak文件中取出所有的图片文件
vector pakinfo=pu.showpakfileinfo(extractresourcepath);
pakheader header=(pakheader)pakinfo.elementat(0);
system.out.println("pak文件信息:");
system.out.println("文件头:");
system.out.println(header);
pakfiletable[] filetable=(pakfiletable[])pakinfo.elementat(1);
for(int i=0;i<filetable.length;i++){
system.out.println("文件table["+i+"]:");
system.out.println(filetable[i]);
}
string restorefilename=null;
byte[] filebuff=null;
for(int i=0;i<filetable.length;i++){
restorefilename=new string(filetable[i].getfilename()).trim();
system.out.println("从pak文件中取出"+restorefilename+"文件数据...");
filebuff=pu.extractresourcefrompak(extractresourcepath,restorefilename);
system.out.println("从pak文件中取出"+restorefilename+"文件数据完成");
}
}}
八、源代码使用简介:
pak过程:j2se版的pakutil将testfiles目录中的三个png文件pak成为test.pak文件。
unpak过程:j2se版的pakutil将testfiles目录中test.pak文件释放到testfiles/extract目录下;j2me版的pakutil从res目录中的test.pak文件读取出其中所包含的3个png文件数据并装入到byte数据,用来构造image对象,大家请运行pakutiltestmidlet.java便可看到输出的信息。
闽公网安备 35060202000074号