如此高级别我有一个从Excel SpreadSheet读取数据的程序将其存储在哈希映射列表中,执行圆顶操作,获取状态,然后将信息写回Excel SpreadSheet。截至目前,如果某种异常导致程序崩溃或程序正常完成,一切都很好。
现在我正在尝试处理如果用户通过按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!");
}
}
答案 0 :(得分:1)
我发现了自己的问题。我正以错误的方式接近这一点。我的代码是正确的唯一问题是在我的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!");
}
}