Partial fix for #56537 - Have Workbook offer a close() method, which in turn closes the NPOIFS or OPC resource from which it was loaded

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1601901 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Nick Burch 2014-06-11 13:48:54 +00:00
parent 1bcf519c7c
commit 47a8f6cf48
4 changed files with 71 additions and 7 deletions

View File

@ -48,7 +48,19 @@ import org.apache.poi.hssf.model.HSSFFormulaParser;
import org.apache.poi.hssf.model.InternalSheet;
import org.apache.poi.hssf.model.InternalWorkbook;
import org.apache.poi.hssf.model.RecordStream;
import org.apache.poi.hssf.record.*;
import org.apache.poi.hssf.record.AbstractEscherHolderRecord;
import org.apache.poi.hssf.record.BackupRecord;
import org.apache.poi.hssf.record.DrawingGroupRecord;
import org.apache.poi.hssf.record.ExtendedFormatRecord;
import org.apache.poi.hssf.record.FontRecord;
import org.apache.poi.hssf.record.LabelRecord;
import org.apache.poi.hssf.record.LabelSSTRecord;
import org.apache.poi.hssf.record.NameRecord;
import org.apache.poi.hssf.record.RecalcIdRecord;
import org.apache.poi.hssf.record.Record;
import org.apache.poi.hssf.record.RecordFactory;
import org.apache.poi.hssf.record.SSTRecord;
import org.apache.poi.hssf.record.UnknownRecord;
import org.apache.poi.hssf.record.aggregates.RecordAggregate.RecordVisitor;
import org.apache.poi.hssf.record.common.UnicodeString;
import org.apache.poi.hssf.util.CellReference;
@ -56,6 +68,7 @@ import org.apache.poi.poifs.filesystem.DirectoryEntry;
import org.apache.poi.poifs.filesystem.DirectoryNode;
import org.apache.poi.poifs.filesystem.EntryUtils;
import org.apache.poi.poifs.filesystem.FilteringDirectoryNode;
import org.apache.poi.poifs.filesystem.NPOIFSFileSystem;
import org.apache.poi.poifs.filesystem.Ole10Native;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.ss.formula.FormulaShifter;
@ -1178,6 +1191,22 @@ public final class HSSFWorkbook extends POIDocument implements org.apache.poi.ss
return style;
}
/**
* Closes the underlying {@link NPOIFSFileSystem} from which
* the Workbook was read, if any. Has no effect on Workbooks
* opened from an InputStream, or newly created ones.
*/
@Override
public void close() throws IOException
{
if (directory != null) {
if (directory.getNFileSystem() != null) {
directory.getNFileSystem().close();
directory = null;
}
}
}
/**
* Method write - write out this workbook to an Outputstream. Constructs
@ -1189,7 +1218,6 @@ public final class HSSFWorkbook extends POIDocument implements org.apache.poi.ss
* @exception IOException if anything can't be written.
* @see org.apache.poi.poifs.filesystem.POIFSFileSystem
*/
@Override
public void write(OutputStream stream)
throws IOException

View File

@ -17,6 +17,7 @@
package org.apache.poi.ss.usermodel;
import java.io.Closeable;
import java.io.IOException;
import java.io.OutputStream;
import java.util.List;
@ -30,7 +31,7 @@ import org.apache.poi.ss.util.CellRangeAddress;
* will construct whether they are reading or writing a workbook. It is also the
* top level object for creating new sheets/etc.
*/
public interface Workbook {
public interface Workbook extends Closeable {
/** Extended windows meta file */
public static final int PICTURE_TYPE_EMF = 2;
@ -350,6 +351,14 @@ public interface Workbook {
*/
void write(OutputStream stream) throws IOException;
/**
* Close the underlying input resource (File or Stream),
* from which the Workbook was read. After closing, the
* Workbook should no longer be used.
* <p>This will have no effect newly created Workbooks.
*/
void close() throws IOException;
/**
* @return the total number of defined names in this workbook
*/

View File

@ -29,6 +29,7 @@ import java.util.Set;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.openxml4j.opc.PackageAccess;
import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.openxml4j.opc.PackageRelationship;
import org.apache.poi.openxml4j.opc.PackageRelationshipCollection;
@ -159,6 +160,21 @@ public abstract class POIXMLDocument extends POIXMLDocumentPart{
onDocumentRead();
context.clear();
}
/**
* Closes the underlying {@link OPCPackage} from which this
* document was read, if there is one
*/
protected void close() throws IOException {
if (pkg != null) {
if (pkg.getPackageAccess() == PackageAccess.READ) {
pkg.revert();
} else {
pkg.close();
}
pkg = null;
}
}
/**
* Write out this document to an Outputstream.

View File

@ -199,10 +199,11 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook, Iterable<X
* Constructs a XSSFWorkbook object given a OpenXML4J <code>Package</code> object,
* see <a href="http://poi.apache.org/oxml4j/">http://poi.apache.org/oxml4j/</a>.
*
* Once you have finished working with the Workbook, you should close the package
* by calling pkg.close, to avoid leaving file handles open.
* <p>Once you have finished working with the Workbook, you should close the package
* by calling either {@link #close()} or {@link OPCPackage#close()}, to avoid
* leaving file handles open.
*
* Creating a XSSFWorkbook from a file-backed OPC Package has a lower memory
* <p>Creating a XSSFWorkbook from a file-backed OPC Package has a lower memory
* footprint than an InputStream backed one.
*
* @param pkg the OpenXML4J <code>OPC Package</code> object.
@ -218,7 +219,7 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook, Iterable<X
* Constructs a XSSFWorkbook object, by buffering the whole stream into memory
* and then opening an {@link OPCPackage} object for it.
*
* Using an {@link InputStream} requires more memory than using a File, so
* <p>Using an {@link InputStream} requires more memory than using a File, so
* if a {@link File} is available then you should instead do something like
* <pre><code>
* OPCPackage pkg = OPCPackage.open(path);
@ -1350,6 +1351,16 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook, Iterable<X
workbook.save(out, xmlOptions);
out.close();
}
/**
* Closes the underlying {@link OPCPackage} from which
* the Workbook was read, if any. Has no effect on newly
* created Workbooks.
*/
@Override
public void close() throws IOException {
super.close();
}
/**
* Returns SharedStringsTable - tha cache of string for this workbook