Il Apache POI 3.8 (ultima versione stabile al momento) crea un file XML temporaneo per ogni foglio (quando si utilizza SXSSF) ma non offre la possibilità di eliminare questi file. Questo fatto rende questa API non utilizzabile perché se esporto 600 MB di dati, avrò 2 file con 600 MB e uno di essi sarà nella cartella temporanea finché non verrà eliminato.
Scavando nel codice, vediamo che la classe SXSSFSheet
ha un'istanza di SheetDataWriter
. Quest'ultima classe è responsabile della scrittura e della gestione del file temporaneo rappresentato dall'istanza File
. L'accesso a questo oggetto consentirebbe di eliminare il file. Tutte queste istanze sono private quindi, in teoria, non è possibile accedervi. Tuttavia, attraverso la riflessione, possiamo accedere all'istanza File
per eliminare questi file utili ma noiosi!
Quanto segue ai metodi consentono di fare ciò. Chiamando lo deleteSXSSFTempFiles
, tutti i file temporanei di quella cartella di lavoro vengono eliminati.
/**
* Returns a private attribute of a class
* @param containingClass The class that contains the private attribute to retrieve
* @param fieldToGet The name of the attribute to get
* @return The private attribute
* @throws NoSuchFieldException
* @throws IllegalAccessException
*/
public static Object getPrivateAttribute(Object containingClass, String fieldToGet) throws NoSuchFieldException, IllegalAccessException {
//get the field of the containingClass instance
Field declaredField = containingClass.getClass().getDeclaredField(fieldToGet);
//set it as accessible
declaredField.setAccessible(true);
//access it
Object get = declaredField.get(containingClass);
//return it!
return get;
}
/**
* Deletes all temporary files of the SXSSFWorkbook instance
* @param workbook
* @throws NoSuchFieldException
* @throws IllegalAccessException
*/
public static void deleteSXSSFTempFiles(SXSSFWorkbook workbook) throws NoSuchFieldException, IllegalAccessException {
int numberOfSheets = workbook.getNumberOfSheets();
//iterate through all sheets (each sheet as a temp file)
for (int i = 0; i < numberOfSheets; i++) {
Sheet sheetAt = workbook.getSheetAt(i);
//delete only if the sheet is written by stream
if (sheetAt instanceof SXSSFSheet) {
SheetDataWriter sdw = (SheetDataWriter) getPrivateAttribute(sheetAt, "_writer");
File f = (File) getPrivateAttribute(sdw, "_fd");
try {
f.delete();
} catch (Exception ex) {
//could not delete the file
}
}
}
}
fonte
2012-10-04 10:05:32
Perché non checkout l'intera base di codice da SVN e costruire che con la formica? O prendi una build notturna di recente? – Gagravarr
@Gagravarr La versione corrente è 3.9-beta1 e volevo davvero evitare di utilizzare API beta per i clienti ... –
Se si desidera utilizzare nuove funzionalità, è necessario utilizzare nuove versioni ... – Gagravarr