-2

我正在使用 Swing 将目录和文件从一台 Windows 服务器复制到另一台 Windows 服务器,效果很好。我希望在复制时 Windows 服务器意外关闭时弹出一个 Joption Messagedialog,因此将其放在 catch 块中,但当服务器关闭时它永远不会显示弹出窗口(我在复制时手动重新启动 Windows 服务器,但看不到弹出窗口)。有人可以帮忙吗,这是代码

try {
    textarea.append("Copying " + sourceFile.getAbsolutePath()
        + "   to " + targetFile.getAbsolutePath());
    is = new BufferedInputStream(new FileInputStream(sourceFile));
    bos = new BufferedOutputStream(new FileOutputStream(targetFile));

    long fileBytes = sourceFile.length();
    long soFar = 0;

    int theByte;

    while ((theByte = bis.read()) != -1) {
        bos.write(theByte);

        setProgress((int) (copiedBytes++ * 100 / totalBytes));
        publish((int) (soFar++ * 100 / fileBytes));
    }

    bis.close();
    bos.close();
    publish(100);
    textarea.append(" Done!\n");
} catch (Exception excep) {
    task.cancel(true);
    bos.flush();
    bis.close();
    bos.close();
    jf2 = new JFrame();
    jf2.setSize(401, 401);
    jf2.setDefaultCloseOperation(jf2.EXIT_ON_CLOSE);
    JOptionPane.showMessageDialog(jf2,
        "The Server is not accessible or it may be down because of Network Issue",
        "ERROR", JOptionPane.ERROR_MESSAGE);
} finally {
    if (bis != null) {
        bis.close();
    }
    if (bos != null) {
        bos.close();
    }
}
4

2 回答 2

2

你的 try-catch 有点尴尬。

您尝试在异常事件和finally块内关闭流。

finally 保证无论如何都会被调用,因此您可以通过使用它来关闭蒸汽来为自己节省一些代码..

try {
    textarea.append("Copying " + sourceFile.getAbsolutePath()
                    + "   to " + targetFile.getAbsolutePath());
    is = new BufferedInputStream(new FileInputStream(sourceFile));
    bos = new BufferedOutputStream(new FileOutputStream(targetFile));

    long fileBytes = sourceFile.length();
    long soFar = 0;

    int theByte;

    while ((theByte = bis.read()) != -1) {
        bos.write(theByte);

        setProgress((int) (copiedBytes++ * 100 / totalBytes));
        publish((int) (soFar++ * 100 / fileBytes));
    }

    // Not required, finally will take care of it...
    //bis.close();
    //bos.close();
    publish(100);
    // !! THIS IS VERY, VERY NAUGHTY !!
    textarea.append(" Done!\n");
} catch (Exception excep) {

    JOptionPane.showMessageDialog(null, "The Server is not accessible or it may be down because of Network Issue", "ERROR", JOptionPane.ERROR_MESSAGE);
    task.cancel(true);

} finally {

    try {
        // techniqually, this gets taken care of when you close the stream,
        // but I tend not to trust it either...
        bos.flush();
    } catch (Exception e) {
    }

    try {
        bis.close();
    } catch (Exception e) {
    }
    try {
        bos.close();
    } catch (Exception e) {
    }

}

看来您的代码正在使用 a SwingWorker,但您textarea.append(" Done!\n")在其中调用。这是非常非常糟糕的。

您的process方法需要能够做到这一点......基本上当您process收到时100,它应该能够更新文本区域。

您还可以允许在其他地方处理异常,允许该doInBackground方法抛出异常。这将允许您使用done方法和get方法来确定是否发生了异常,其额外的好处done是在 EDT 中调用

于 2012-12-23T03:55:55.943 回答
1

首先,我不喜欢所有手动资源管理,所以我将其更改为使用 Java 7 的try-with-resources来为您执行此操作,这允许删除 finally 块和所有实例close()flush()(顺便说一句,关闭电话会刷新,所以无论如何你都不需要。

其次,我不知道该消息框声明是否有效,Javadoc forJOptionPane.showMessageDialog()说第一个参数应该是Component parentComponent,但是您要声明一个新的不可见 JFrame ,所以如果您发布的这段代码在 JFrame 类中,this而是通过。总的来说,我会试一试:

try(BufferedInputStream bis = new BufferedInputStream(new FileInputStream(sourceFile));
    BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(targetFile)))
{
    textarea.append("Copying " + sourceFile.getAbsolutePath() +
                    " to " + targetFile.getAbsolutePath());
    long fileBytes = sourceFile.length();
    long soFar = 0;
    int theByte;
    while((theByte = bis.read()) != -1)
    {
        bos.write(theByte);
        setProgress((int) (copiedBytes++ * 100 / totalBytes));
        publish((int) (soFar++ * 100 / fileBytes));
    }
    publish(100);
    textarea.append(" Done!\n");
}
catch(Exception excep)
{
    task.cancel(true);
    JOptionPane.showMessageDialog(this, "The Server is not accessible or it may be down because of Network Issue", "ERROR", JOptionPane.ERROR_MESSAGE);
}
于 2012-12-23T03:50:40.427 回答