?? pakutil.java
字號(hào):
package cn.org.matrix.gmatrix.gameLab.util.pak;
import java.io.*;
import java.util.Vector;
/**
* Pak工具類
* 功能:
* 從Pak文件中取出png圖片,構(gòu)造byte數(shù)組(可以用來構(gòu)造Image對(duì)象)
* @author cleverpig
*
*/
public class PakUtil {
public PakUtil(){
}
/**
* 計(jì)算文件位移的起始點(diǎn)
* @return 文件位移的起始點(diǎn)
*/
private long workOutOffsetStart(PakHeader header){
//計(jì)算出文件頭+文件table的長(zhǎng)度
return PakHeader.size()+header.getNumFileTableEntries()*PakFileTable.size();
}
/**
* 從DataInputStream讀取char數(shù)組
* @param dis DataInputStream
* @param readLength 讀取長(zhǎng)度
* @return char數(shù)組
* @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 文件表總數(shù)
* @return 文件table數(shù)組
* @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數(shù)組
* @param dis DataInputStream
* @param fileTable PakFileTable
* @return byte數(shù)組
* @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("讀取數(shù)據(jù)長(zhǎng)度不正確");
return null;
}
else{
decryptBuff(fileBuff,readLength,header);
}
return fileBuff;
}
/**
* 使用文件頭中的密碼對(duì)數(shù)據(jù)進(jìn)行解密
* @param buff 被解密的數(shù)據(jù)
* @param buffLength 數(shù)據(jù)的長(zhǎng)度
* @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數(shù)組
* @param pakResourceURL pak文件的資源路徑
* @param extractResourceName pak文件中將要被取出的文件名
* @return byte數(shù)組
* @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數(shù)組的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+"文件數(shù)據(jù)...");
fileBuff=pu.extractResourceFromPak(extractResourcePath,restoreFileName);
System.out.println("從Pak文件中取出"+restoreFileName+"文件數(shù)據(jù)完成");
}
}
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -