Java 关闭 Hook 并写入 Excel 工作表

标签 java excel apache-poi shutdown-hook

如此高级,我有一个程序,它从 Excel SpreadSheet 读取数据,将其存储在 HashMap 列表中,执行圆顶操作,获取状态,然后将信息写回 Excel SpreadSheet。截至目前,如果某种异常导致程序崩溃或程序正常完成,一切都很好。

现在我正在尝试处理如果用户通过按 Ctrl + C 终止运行会发生什么。我认为最好的方法是实现我自己的关闭 Hook 。

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() 中,我将其注册为关闭 Hook

TerminationThread sH = new TerminationThread();
Runtime.getRuntime().addShutdownHook(sH);

当程序进入关闭 Hook 时,一切都很好,直到它到达写入文件的部分,然后它开始抛出一堆异常,最后我得到一个损坏的电子表格。

这是我编写的代码:

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 电子表格的对象在写入完成之前被删除,或者在写入数据之前存储数据的 HashMap 列表被删除。

我已经将线程连接视为我的问题的可能解决方案,但在查看它们后,我认为它们并不是我的问题的解决方案。

所以我想我的问题是如何让它按照我希望的方式工作

干杯, 迈纳特

编辑:这是异常(exception)

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 block 中我也有一个文件写入。因此,当我的程序不间断地一直执行时,它将执行写入两次,这是异常的原因。我通过检查是否执行了finally block 以及是否跳过了关闭钩子(Hook)中的写入来解决了这个问题。

最后:

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);
}

关闭 Hook

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!");
    }
}

最佳答案

好吧,我找到了我自己的问题。我以错误的方式处理这个问题。我的代码是正确的,唯一的问题是在我的finally block 中我也有一个文件写入。因此,当我的程序不间断地一直执行时,它将执行写入两次,这是异常的原因。我通过检查是否执行了finally block 以及是否跳过了关闭钩子(Hook)中的写入来解决了这个问题。

最后:

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);
}

关闭 Hook

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!");
    }
}

关于Java 关闭 Hook 并写入 Excel 工作表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24187209/

相关文章:

vba - 在现有 If block 中添加新的 If 语句

vba - 显示多个错误时获取行号的消息框

java - 使用 openxmlformats 在条形图中创建目标标记

java - 如何在 gitlab-ci.yml 中向我的 gitlab-ci 作业添加计时器以使其在 1 分钟内停止

excel - 创建一个 Excel 宏以跨可变/未知数量的列复制公式?

java - 如何在 while 循环中增加行计数器变量?

java - 如何使用 XSSF (Apache POI 3.8) 调整图表大小?

java - 两个短整数的异或

java - 在 rest api 中返回 json 中的任何异常

java - 在 Spring Security 2.06 中实现自定义 AuthenticationProvider