📄 compoundfile.java
字号:
{
if (psnames[i].equalsIgnoreCase(STANDARD_PROPERTY_SETS[j]))
{
standard = true;
ReadPropertyStorage rps = new ReadPropertyStorage(ps, null, i);
readPropertySets.put(psnames[i], rps);
}
}
if (!standard)
{
try
{
byte[] data = null;
if (ps.size > 0 )
{
data = readCompoundFile.getStream(ps.name);
}
else
{
data = new byte[0];
}
ReadPropertyStorage rps = new ReadPropertyStorage(ps, data, i);
readPropertySets.put(psnames[i], rps);
additionalPropertySets.add(rps);
if (data.length > SMALL_BLOCK_THRESHOLD)
{
int blocks = getBigBlocksRequired(data.length);
blocksRequired += blocks;
}
else
{
int blocks = getSmallBlocksRequired(data.length);
numSmallBlocks += blocks;
}
}
catch (BiffException e)
{
logger.error(e);
throw new CopyAdditionalPropertySetsException();
}
}
}
additionalPropertyBlocks = blocksRequired;
}
/**
* Writes out the excel file in OLE compound file format
*
* @exception IOException
*/
public void write() throws IOException
{
writeHeader();
writeExcelData();
writeDocumentSummaryData();
writeSummaryData();
writeAdditionalPropertySets();
writeSmallBlockDepot();
writeSmallBlockDepotChain();
writeBigBlockDepot();
writePropertySets();
// Don't flush or close the stream - this is handled by the enclosing File
// object
}
/**
* Writes out any additional property sets
*/
private void writeAdditionalPropertySets() throws IOException
{
if (additionalPropertySets == null)
{
return;
}
for (Iterator i = additionalPropertySets.iterator(); i.hasNext() ;)
{
ReadPropertyStorage rps = (ReadPropertyStorage) i.next();
byte[] data = rps.data;
if (data.length > SMALL_BLOCK_THRESHOLD)
{
int numBlocks = getBigBlocksRequired(data.length);
int requiredSize = numBlocks * BIG_BLOCK_SIZE;
out.write(data, 0, data.length);
byte[] padding = new byte[requiredSize - data.length];
out.write(padding, 0, padding.length);
}
}
// if (rps.propertyStorage.name.equals("Module1"))
/*
{
System.out.println("terminating");
out.flush();
out.close();
System.exit(1);
}
*/
}
/**
* Writes out the excel data, padding it out with empty bytes as
* necessary
* Also write out empty
*
* @exception IOException
*/
private void writeExcelData() throws IOException
{
out.write(excelData, 0, size);
byte[] padding = new byte[requiredSize - size];
out.write(padding);
}
/**
* Write out the document summary data. This is just blank
*
* @exception IOException
*/
private void writeDocumentSummaryData() throws IOException
{
byte[] padding = new byte[SMALL_BLOCK_THRESHOLD];
// Write out the summary information
out.write(padding);
}
/**
* Write out the summary data. This is just blank
*
* @exception IOException
*/
private void writeSummaryData() throws IOException
{
byte[] padding = new byte[SMALL_BLOCK_THRESHOLD];
// Write out the summary information
out.write(padding);
}
/**
* Writes the compound file header
*
* @exception IOException
*/
private void writeHeader() throws IOException
{
// Build up the header array
byte[] headerBlock = new byte[BIG_BLOCK_SIZE];
byte[] extensionBlockData = new byte[BIG_BLOCK_SIZE * numExtensionBlocks];
// Copy in the identifier
System.arraycopy(IDENTIFIER, 0, headerBlock, 0, IDENTIFIER.length);
// Copy in some magic values - no idea what they mean
headerBlock[0x18] = 0x3e;
headerBlock[0x1a] = 0x3;
headerBlock[0x1c] = (byte) 0xfe;
headerBlock[0x1d] = (byte) 0xff;
headerBlock[0x1e] = 0x9;
headerBlock[0x20] = 0x6;
headerBlock[0x39] = 0x10;
// Set the number of BBD blocks
IntegerHelper.getFourBytes(numBigBlockDepotBlocks,
headerBlock,
NUM_BIG_BLOCK_DEPOT_BLOCKS_POS);
// Set the small block depot chain
IntegerHelper.getFourBytes(sbdStartBlockChain,
headerBlock,
SMALL_BLOCK_DEPOT_BLOCK_POS);
// Set the number of blocks in the small block depot chain
IntegerHelper.getFourBytes(numSmallBlockDepotChainBlocks,
headerBlock,
NUM_SMALL_BLOCK_DEPOT_BLOCKS_POS);
// Set the extension block
IntegerHelper.getFourBytes(extensionBlock,
headerBlock,
EXTENSION_BLOCK_POS);
// Set the number of extension blocks to be the number of BBD blocks - 1
IntegerHelper.getFourBytes(numExtensionBlocks,
headerBlock,
NUM_EXTENSION_BLOCK_POS);
// Set the root start block
IntegerHelper.getFourBytes(rootStartBlock,
headerBlock,
ROOT_START_BLOCK_POS);
// Set the block numbers for the BBD. Set the BBD running
// after the excel data and summary information
int pos = BIG_BLOCK_DEPOT_BLOCKS_POS;
// See how many blocks fit into the header
int blocksToWrite = Math.min(numBigBlockDepotBlocks,
(BIG_BLOCK_SIZE -
BIG_BLOCK_DEPOT_BLOCKS_POS)/4);
int extensionBlock = 0;
int blocksWritten = 0;
for (int i = 0 ; i < blocksToWrite; i++)
{
IntegerHelper.getFourBytes(bbdStartBlock + i,
headerBlock,
pos);
pos += 4;
blocksWritten++;
}
// Pad out the rest of the header with blanks
for (int i = pos; i < BIG_BLOCK_SIZE; i++)
{
headerBlock[i] = (byte) 0xff;
}
out.write(headerBlock);
// Write out the extension blocks
pos = 0;
for (int extBlock = 0; extBlock < numExtensionBlocks; extBlock++)
{
blocksToWrite = Math.min(numBigBlockDepotBlocks - blocksWritten,
BIG_BLOCK_SIZE/4 -1);
for(int j = 0 ; j < blocksToWrite; j++)
{
IntegerHelper.getFourBytes(bbdStartBlock + blocksWritten + j,
extensionBlockData,
pos);
pos += 4;
}
blocksWritten += blocksToWrite;
// Indicate the next block, or the termination of the chain
int nextBlock = (blocksWritten == numBigBlockDepotBlocks) ?
-2 : extBlock+1 ;
IntegerHelper.getFourBytes(nextBlock, extensionBlockData, pos);
pos +=4;
}
if (numExtensionBlocks > 0)
{
// Pad out the rest of the extension block with blanks
for (int i = pos; i < extensionBlockData.length; i++)
{
extensionBlockData[i] = (byte) 0xff;
}
out.write(extensionBlockData);
}
}
/**
* Checks that the data can fit into the current BBD block. If not,
* then it moves on to the next block
*
* @exception IOException
*/
private void checkBbdPos() throws IOException
{
if (bbdPos >= BIG_BLOCK_SIZE)
{
// Write out the extension block. This will simply be the next block
out.write(bigBlockDepot);
// Create a new block
bigBlockDepot = new byte[BIG_BLOCK_SIZE];
bbdPos = 0;
}
}
/**
* Writes out the big block chain
*
* @param startBlock the starting block of the big block chain
* @param numBlocks the number of blocks in the chain
* @exception IOException
*/
private void writeBlockChain(int startBlock, int numBlocks)
throws IOException
{
int blocksToWrite = numBlocks - 1;
int blockNumber = startBlock + 1;
while (blocksToWrite > 0)
{
int bbdBlocks = Math.min(blocksToWrite, (BIG_BLOCK_SIZE - bbdPos)/4);
for (int i = 0 ; i < bbdBlocks; i++)
{
IntegerHelper.getFourBytes(blockNumber, bigBlockDepot, bbdPos);
bbdPos +=4 ;
blockNumber++;
}
blocksToWrite -= bbdBlocks;
checkBbdPos();
}
// Write the end of the block chain
IntegerHelper.getFourBytes(-2, bigBlockDepot, bbdPos);
bbdPos += 4;
checkBbdPos();
}
/**
* Writes the block chains for the additional property sets
*
* @exception IOException
*/
private void writeAdditionalPropertySetBlockChains() throws IOException
{
if (additionalPropertySets == null)
{
return;
}
int blockNumber = excelDataStartBlock + excelDataBlocks + 16;
for (Iterator i = additionalPropertySets.iterator(); i.hasNext() ; )
{
ReadPropertyStorage rps = (ReadPropertyStorage) i.next();
if (rps.data.length > SMALL_BLOCK_THRESHOLD)
{
String psname = rps.propertyStorage.name;
int numBlocks = getBigBlocksRequired(rps.data.length);
writeBlockChain(blockNumber, numBlocks);
blockNumber += numBlocks;
}
}
}
/**
* Writes out the chains for the small block depot
*/
private void writeSmallBlockDepotChain() throws IOException
{
if (sbdStartBlockChain == -2)
{
return;
}
byte[] smallBlockDepotChain =
new byte[numSmallBlockDepotChainBlocks * BIG_BLOCK_SIZE];
int pos = 0;
int sbdBlockNumber = 1;
for (Iterator i = additionalPropertySets.iterator(); i.hasNext() ; )
{
ReadPropertyStorage rps = (ReadPropertyStorage) i.next();
if (rps.data.length <= SMALL_BLOCK_THRESHOLD &&
rps.data.length != 0)
{
int numSmallBlocks = getSmallBlocksRequired(rps.data.length);
for (int j = 0 ; j < numSmallBlocks - 1 ; j++)
{
IntegerHelper.getFourBytes(sbdBlockNumber,
smallBlockDepotChain,
pos);
pos += 4;
sbdBlockNumber++;
}
// Write out the end of chain
IntegerHelper.getFourBytes(-2, smallBlockDepotChain, pos);
pos += 4;
sbdBlockNumber++;
}
}
out.write(smallBlockDepotChain);
}
/**
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -