.zip 文件没有被删除,但也没有抛出任何异常

.zip file isn't deleted but neither throw any exception

我已经创建了一个应用程序,其中包含我通常在我的电脑上使用的实用程序(例如将关闭发送到 cmd.exe),并且当一些朋友要求我将其提供给他们时,我试图添加一个更新系统检查服务器上的更新,以便更轻松地始终更新其版本。

问题是我一直在网上搜索任何解决方案,但他们都告诉我使用 .close() 并且我的文件在不再需要它后立即拥有它。当我运行它时,一切正常,没有抛出异常,所以我不知道哪里出了问题。

全班:

public class Main_Gui extends JFrame {

        private Thread worker;
        private final String root = "update/";

        private JTextArea outText;
        private JButton cancel;
        private JButton launch;
        private JScrollPane sp;
        private JPanel pan1;
        private JPanel pan2;

        private String zipFile = "Actualización.zip";
        private String path = "http://ritsu.hol.es/url.html";
        private String TITLE = "RitsUtilities | Actualizador";

        public Main_Gui() {
            initComponents();
            outText.setText("Conectando con el servidor...");
            download();
        }

        private void initComponents() {

            try {
                UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
            } catch (Exception e) {
                e.printStackTrace();
            }
            setTitle(TITLE);
            setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

            pan1 = new JPanel();
            pan1.setLayout(new BorderLayout());

            pan2 = new JPanel();
            pan2.setLayout(new FlowLayout());

            outText = new JTextArea();
            sp = new JScrollPane();
            sp.setViewportView(outText);

            launch = new JButton("Ejecutar RitsUtilities");
            launch.setEnabled(false);
            launch.addActionListener(new ActionListener() {

                public void actionPerformed(ActionEvent e) {
                    String[] run = { "java", "-jar", "RitsUtilities.jar" };
                    try {
                        Runtime.getRuntime().exec(run);
                    } catch (Exception ex) {
                        ex.printStackTrace();
                    }
                    System.exit(0);
                    launch();
                }
            });
            pan2.add(launch);

            cancel = new JButton("Salir");
            cancel.addActionListener(new ActionListener() {

                public void actionPerformed(ActionEvent e) {
                    System.exit(0);
                }
            });
            pan2.add(cancel);
            pan1.add(sp, BorderLayout.CENTER);
            pan1.add(pan2, BorderLayout.SOUTH);

            add(pan1);
            pack();
            setSize(500, 400);
            setLocationRelativeTo(null);

        }

        private void download() {

            worker = new Thread(new Runnable() {

                public void run() {
                    try {
                        downloadFile(getDownloadLinkFromHost());
                        unzip();
                        copyFiles(new File(root), new File("").getAbsolutePath());
                        cleanup();
                        launch.setEnabled(true);
                        outText.setText(outText.getText() + "\n¡Actualización completada con éxito!");
                    } catch (Exception e) {
                        e.printStackTrace();
                        JOptionPane.showMessageDialog(null, "Ha ocurrido un error al descargar y descomprimir la actualización.", "Error 1", JOptionPane.WARNING_MESSAGE);
                    }
                }
            });
            worker.start();
        }

        private void launch() {
            String[] run = { "java", "-jar", "update app.jar" };
            try {
                Runtime.getRuntime().exec(run);
            } catch (Exception ex) {
                ex.printStackTrace();
            }
            System.exit(0);
        }

        private void cleanup() {
            outText.setText(outText.getText() + "\nLimpiando archivos temporales...");
            remove(new File(root));
            new File(root).delete();
        }

        private void remove(File f) {
            File[] files = f.listFiles();
            for (File ff : files) {
                if (ff.isDirectory()) {
                    remove(ff);
                    ff.delete();
                } else {
                    ff.delete();
                }
            }

        }

        private void copyFiles(File f, String dir) throws IOException {
            File[] files = f.listFiles();
            for (File ff : files) {
                if (ff.isDirectory()) {
                    new File(dir + "/" + ff.getName()).mkdir();
                    copyFiles(ff, dir + "/" + ff.getName());
                } else {
                    copy(ff.getAbsolutePath(), dir + "/" + ff.getName());
                }

            }
        }

        public void copy(String srFile, String dtFile) throws FileNotFoundException, IOException {

            File f1 = new File(srFile);
            File f2 = new File(dtFile);

            InputStream in = new FileInputStream(f1);
            OutputStream out = new FileOutputStream(f2);

            byte[] buf = new byte[1024];
            int len;
            while ((len = in.read(buf)) > 0) {
                out.write(buf, 0, len);
            }
            in.close();
            out.close();
        }

        private void unzip() throws IOException {
            int BUFFER = 2048;
            BufferedOutputStream dest = null;
            BufferedInputStream is = null;
            ZipEntry entry;
            ZipFile zipfile = new ZipFile(zipFile);
            Enumeration e = zipfile.entries();
            (new File(root)).mkdir();
            while (e.hasMoreElements()) {
                entry = (ZipEntry) e.nextElement();
                outText.setText(outText.getText() + "\nExtrayendo: " + entry);
                if (entry.isDirectory())
                    (new File(root + entry.getName())).mkdir();
                else {
                    (new File(root + entry.getName())).createNewFile();
                    is = new BufferedInputStream(zipfile.getInputStream(entry));
                    int count;
                    byte data[] = new byte[BUFFER];
                    FileOutputStream fos = new FileOutputStream(root + entry.getName());
                    dest = new BufferedOutputStream(fos, BUFFER);
                    while ((count = is.read(data, 0, BUFFER)) != -1) {
                        dest.write(data, 0, count);
                    }
                    dest.flush();
                    dest.close();
                    is.close();
                }
            }

        }

        private void downloadFile(String link) throws MalformedURLException, IOException {
            URL url = new URL(link);
            URLConnection conn = url.openConnection();
            InputStream is = conn.getInputStream();
            long max = conn.getContentLength();
            outText.setText(outText.getText() + "\n" + "Descargando archivo...\nTamaño de la actualización(comprimida): " + max + " Bytes");
            BufferedOutputStream fOut = new BufferedOutputStream(new FileOutputStream(new File(zipFile)));
            byte[] buffer = new byte[32 * 1024];
            int bytesRead = 0;
            int in = 0;
            while ((bytesRead = is.read(buffer)) != -1) {
                in += bytesRead;
                fOut.write(buffer, 0, bytesRead);
            }
            fOut.flush();
            fOut.close();

            is.close();
            outText.setText(outText.getText() + "\n¡Descarga completada!");

        }

        private String getDownloadLinkFromHost() throws MalformedURLException, IOException {

            URL url = new URL(path);
            InputStream html = null;
            html = url.openStream();
            int c = 0;
            StringBuilder buffer = new StringBuilder("");

            while (c != -1) {
                c = html.read();
                buffer.append((char) c);
            }
            return buffer.substring(buffer.indexOf("[url]") + 5, buffer.indexOf("[/url]"));
        }

        public static void main(String args[]) {
            java.awt.EventQueue.invokeLater(new Runnable() {

                public void run() {
                    new Main_Gui().setVisible(true);
                }
            });
        }

    }

编辑:private String zipFile = "Actualización.zip"; 更改为 private String zipFile = "Update.zip"; 但仍只是删除临时 files/directories 而不是那个 "Update.zip" 文件夹应用下载。

如果无法删除文件,您使用的File#delete() 方法不会抛出错误,它returns false。这记录在 Javadoc 中,还有一个替代解决方案(强调我的):

Deletes the file or directory denoted by this abstract pathname. If this pathname denotes a directory, then the directory must be empty in order to be deleted.
Note that the Files class defines the delete method to throw an IOException when a file cannot be deleted. This is useful for error reporting and to diagnose why a file cannot be deleted.

我建议改进您的 remove(File f) 方法。为 ff.delete() 的布尔值 return 添加一些检查,这将告诉您文件是否实际被删除。

此外,您可以在该方法中添加一些日志,这样您就可以调试实际在做什么,也许它没有看到文件或其他东西。

最后一条评论。你应该让你的代码更加模块化。创建更多的抽象并给它们每个人一个简单的任务。这就是面向对象设计的本质。然后,您可以为每个对象编写一些 JUnit 测试,并且每次进行更改时都可以 运行 测试。我建议你看看 Cohesion

上的这篇文章

它终于开始工作了,只是在 download() 中的 运行() 上添加了一个强制删除,所以现在我的代码看起来像

public void run() {
                try {
                    downloadFile(getDownloadLinkFromHost());
                    unzip();
                    copyFiles(new File(root), new File("").getAbsolutePath());
                    cleanup();
                    launch.setEnabled(true);
                +   System.gc();
                +   File tmpf = new File(zipFile);
                +   tmpf.deleteOnExit();
                    outText.setText(outText.getText() + "\n¡Actualización completada con éxito!");
                } catch (Exception e) {
                    e.printStackTrace();
                    JOptionPane.showMessageDialog(null, "Ha ocurrido un error al descargar y descomprimir la actualización.", "Error 1", JOptionPane.WARNING_MESSAGE);
                }
            }

我很确定有更好的方法可以做到这一点,但那个似乎对我有用。

感谢所有回答并试图帮助我的人。 =D