📄 archive.java.svn-base
字号:
/*
* Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved.
* Original author: Edmund Wagner
* Creation date: 22.05.2007
*
* Source: $HeadURL$
* Last changed: $LastChangedDate$
*
* the unrar licence applies to all junrar source and binary distributions
* you are not allowed to use this source to re-create the RAR compression algorithm
*
* Here some html entities which can be used for escaping javadoc tags:
* "&": "&" or "&"
* "<": "<" or "<"
* ">": ">" or ">"
* "@": "@"
*/
package de.innosystec.unrar;
import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import de.innosystec.unrar.exception.RarException;
import de.innosystec.unrar.exception.RarException.RarExceptionType;
import de.innosystec.unrar.io.IReadOnlyAccess;
import de.innosystec.unrar.io.ReadOnlyAccessByteArray;
import de.innosystec.unrar.io.ReadOnlyAccessInputStream;
import de.innosystec.unrar.rarfile.AVHeader;
import de.innosystec.unrar.rarfile.BaseBlock;
import de.innosystec.unrar.rarfile.BlockHeader;
import de.innosystec.unrar.rarfile.CommentHeader;
import de.innosystec.unrar.rarfile.EndArcHeader;
import de.innosystec.unrar.rarfile.FileHeader;
import de.innosystec.unrar.rarfile.MainHeader;
import de.innosystec.unrar.rarfile.MarkHeader;
import de.innosystec.unrar.rarfile.ProtectHeader;
import de.innosystec.unrar.rarfile.SignHeader;
import de.innosystec.unrar.rarfile.UnrarHeadertype;
import de.innosystec.unrar.unpack.ComprDataIO;
import de.innosystec.unrar.unpack.Unpack;
/**
* DOCUMENT ME
*
* @author $LastChangedBy$
* @version $LastChangedRevision$
*/
public class Archive {
private static Log logger = LogFactory.getLog(Archive.class.getName());
private List<BaseBlock> headers = new ArrayList<BaseBlock>();
private IReadOnlyAccess file;
private ComprDataIO dataIO = new ComprDataIO(this);
private MainHeader mainHeader = null;
private Unpack unpack;
/**
* create a new archive object using the given file
* @param file the file to extract
* @throws RarException
*/
public Archive(IReadOnlyAccess file) throws RarException {
this.file = file;
try{
readHeaders();
}catch (Exception e) {
logger.warn("exception in archive constructor maybe file is encrypted or currupt",e);
//ignore exceptions to allow exraction of working files in corrupt archive
}
}
/**
*
* @return whether the archive is encrypted
*/
public boolean isEncrypted()
{
if(mainHeader!=null){
return mainHeader.isEncrypted();
}else{
throw new NullPointerException("mainheader is null");
}
}
/**
* Read the headers of the archive
* @throws RarException
*/
private void readHeaders() throws RarException{
int toRead = 0;
while(true){
int size = 0;
long newpos = 0;
byte[] baseBlockBuffer =new byte[BaseBlock.BaseBlockSize];
long position = file.getPosition();
logger.info("\n--------reading header--------");
size = file.readBytes(baseBlockBuffer, BaseBlock.BaseBlockSize);
if (size == 0){
break;
}
BaseBlock block = new BaseBlock(baseBlockBuffer);
block.setPositionInFile(position);
switch(block.getHeaderType())
{
case MarkHeader:
MarkHeader markHead = new MarkHeader(block);
headers.add(markHead);
markHead.print();
break;
case MainHeader:
int mainHeaderSize = 0;
toRead = block.hasEncryptVersion() ? MainHeader.mainHeaderSizeWithEnc : MainHeader.mainHeaderSize;
byte[] mainbuff = new byte[toRead];
mainHeaderSize = file.readBytes(mainbuff, toRead);
MainHeader mainhead =new MainHeader(block,mainbuff);
headers.add(mainhead);
this.mainHeader = mainhead;
if(mainHeader.isEncrypted()){
throw new RarException(RarExceptionType.rarEncryptedException);
}
mainhead.print();
break;
case SignHeader:
int signHeaderSize = 0;
toRead = SignHeader.signHeaderSize;
byte[] signBuff = new byte[toRead];
signHeaderSize = file.readBytes(signBuff, toRead);
SignHeader signHead = new SignHeader(block,signBuff);
headers.add(signHead);
logger.info("HeaderType: SignHeader");
break;
case AvHeader:
int avHeaderSize = 0;
toRead = AVHeader.avHeaderSize;
byte[] avBuff = new byte[toRead];
avHeaderSize = file.readBytes(avBuff, toRead);
AVHeader avHead = new AVHeader(block,avBuff);
headers.add(avHead);
logger.info("headertype: AVHeader");
break;
case CommHeader:
int commHeaderSize = 0;
toRead = CommentHeader.commentHeaderSize;
byte[] commBuff = new byte[toRead];
commHeaderSize = file.readBytes(commBuff, toRead);
CommentHeader commHead = new CommentHeader(block,commBuff);
headers.add(commHead);
logger.info("method: "+commHead.getUnpMethod()+"; 0x"+Integer.toHexString(commHead.getUnpMethod()));
newpos = commHead.getPositionInFile() + commHead.getHeaderSize();
file.setPosition(newpos);
break;
case EndArcHeader:
toRead = 0;
toRead += block.hasArchiveDataCRC() ? EndArcHeader.endArcArchiveDataCrcSize : 0;
toRead += block.hasVolumeNumber() ? EndArcHeader.endArcVolumeNumberSize : 0;
EndArcHeader endArcHead;
if(toRead > 0){
int endArcHeaderSize = 0;
byte[] endArchBuff = new byte[toRead];
endArcHeaderSize = file.readBytes(endArchBuff, toRead);
endArcHead = new EndArcHeader(block,endArchBuff);
logger.info("HeaderType: endarch\ndatacrc:"+endArcHead.getArchiveDataCRC());
}else{
logger.info("HeaderType: endarch - no Data");
endArcHead = new EndArcHeader(block,null);
}
headers.add(endArcHead);
return;
default:
byte[] blockHeaderBuffer = new byte[BlockHeader.blockHeaderSize];
int bhsize = file.readBytes(blockHeaderBuffer, BlockHeader.blockHeaderSize);
BlockHeader blockHead = new BlockHeader(block,blockHeaderBuffer);
switch(blockHead.getHeaderType())
{
case NewSubHeader:
case FileHeader:
toRead = blockHead.getHeaderSize()-BlockHeader.BaseBlockSize-BlockHeader.blockHeaderSize;
byte[] fileHeaderBuffer = new byte[toRead];
int fhsize = file.readBytes(fileHeaderBuffer, toRead);
FileHeader fh = new FileHeader(blockHead,fileHeaderBuffer);
fh.print();
headers.add(fh);
newpos = fh.getPositionInFile() + fh.getHeaderSize() + fh.getFullPackSize();
file.setPosition(newpos);
break;
case ProtectHeader:
toRead = blockHead.getHeaderSize()-BlockHeader.BaseBlockSize-BlockHeader.blockHeaderSize;
byte[] protectHeaderBuffer = new byte[toRead];
int phsize = file.readBytes(protectHeaderBuffer, toRead);
ProtectHeader ph = new ProtectHeader(blockHead,protectHeaderBuffer);
logger.info("totalblocks"+ph.getTotalBlocks());
newpos = ph.getPositionInFile() + ph.getHeaderSize();
file.setPosition(newpos);
break;
default:
logger.warn("Unknown Header");
throw new RarException(RarExceptionType.notRarArchive);
}
}
}
}
/**
* @return returns all headers of the archive
*/
public List<BaseBlock> getHeaders() {
return headers;
}
/**
* @return returns all file headers of the archive
*/
public List<FileHeader> getFileHeaders(){
List<FileHeader> list = new ArrayList<FileHeader>();
for (BaseBlock block: headers) {
if(block.getHeaderType().equals(UnrarHeadertype.FileHeader)){
list.add((FileHeader)block);
}
}
return list;
}
/**
* Extract the file specified by the given header and write it to the supplied output stream
* @param header the header to be extracted
* @param os the outputstream
* @throws RarException
*/
public void extractFile(BaseBlock header,OutputStream os) throws RarException{
FileHeader hd = null;
if(header instanceof FileHeader){
hd = (FileHeader) header;
if(getHeaders().contains(hd)){
try {
doExtractFile(hd, os);
} catch (Exception e) {
if(e instanceof RarException){
throw new RarException((RarException)e);
}else{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -