如此高级,我有一个程序可以从 Excel 电子表格中读取数据,并将其存储在哈希映射列表中,执行圆顶操作,获取状态,然后将信息写回 Excel 电子表格。截至目前,如果某种异常导致程序崩溃或程序正常完成,一切都很好。
现在我正在尝试处理如果用户通过按 Ctrl + C 来终止运行的情况。我认为最好的方法是实现我自己的关闭挂钩。
private static class TerminationThread extends Thread
{
public void run() {
for(UserCredential user : creds)
{
Accel.setRow(user.getMap(), user.getRowIndex());
}
try {
Accel.writeToFile();
} catch (IOException e) {
e.printStackTrace();
}
}
}
在我的 Main() 中,我将其注册为关闭挂钩
TerminationThread sH = new TerminationThread();
Runtime.getRuntime().addShutdownHook(sH);
当程序进入关闭挂钩时,一切都很好,直到它到达写入文件的部分,然后它开始抛出一堆异常,最后我得到一个损坏的电子表格。
这是我的编写代码:
public void writeToFile() throws IOException
{
try
{
fileOut = new FileOutputStream(theFile);
theWorkbook.write(fileOut);
}
catch (IOException e)
{
throw new IOException("Exception in writeToFile(). " + e);
}
finally
{
try
{
fileOut.flush();
fileOut.close();
}
catch(IOException e)
{
throw new IOException("Exception closing FileOutputStream. " + e);
}
}
}
我假设正在发生的是,处理我的 excel 电子表格的对象在写入完成之前被清除,或者我在写入之前存储数据的哈希映射列表被清除。
我已将 Thread Joins 视为解决我的问题的一种可能方法,但在查看它们时,我认为它们不是我问题的解决方案。
所以我想我的问题是我如何让它以我希望的方式工作
干杯,迈纳特
编辑:这是例外
Exception in thread "Thread-4" org.apache.xmlbeans.impl.values.XmlValueDisconnectedException
at org.apache.xmlbeans.impl.values.XmlObjectBase.check_orphaned(XmlObjectBase.java:1213)
at org.apache.xmlbeans.impl.values.XmlObjectBase.newCursor(XmlObjectBase.java:243)
at org.apache.xmlbeans.impl.values.XmlComplexContentImpl.arraySetterHelper(XmlComplexContentImpl.java:1073)
at org.openxmlformats.schemas.spreadsheetml.x2006.main.impl.CTDefinedNamesImpl.setDefinedNameArray(Unknown Source)
at org.apache.poi.xssf.usermodel.XSSFWorkbook.saveNamedRanges(XSSFWorkbook.java:1270)
at org.apache.poi.xssf.usermodel.XSSFWorkbook.commit(XSSFWorkbook.java:1291)
at org.apache.poi.POIXMLDocumentPart.onSave(POIXMLDocumentPart.java:313)
at org.apache.poi.POIXMLDocument.write(POIXMLDocument.java:173)
at com.cba.statuschecker.ExcelManager.writeToFile(ExcelManager.java:179)
at com.cba.statuschecker.Main$TerminationThread.run(Main.java:495)
编辑2:好吧,我想出了自己的问题。我以错误的方式接近这个。我的代码是正确的,唯一的问题是在我的 finally 块中我还有一个文件写入。因此,当我的程序在没有中断的情况下一直执行时,它会执行两次写入,这是导致异常的原因。我通过检查是否执行了 finally 块以及是否跳过了关闭挂钩中的写入来解决此问题。
最后:
finally
{
// Print out statuses
printStatus();
for(UserCredential user : creds)
{
Accel.setRow(user.getMap(), user.getRowIndex());
}
try {
Accel.writeToFile();
} catch (IOException e) {
e.printStackTrace();
}
didFinally = true;
LOGGER.info(Log("Fin."));
System.exit(0);
}
关机挂钩
private static class TerminationThread extends Thread
{
public void run() {
System.out.println("Shutdown Initiated...");
if(!didFinally){
for(UserCredential user : creds)
{
Accel.setRow(user.getMap(), user.getRowIndex());
}
System.out.println("Writing to file...");
try {
Accel.writeToFile();
} catch (IOException e) {
e.printStackTrace();
}
}
System.out.println("Terminated!");
}
}