@fattan
программист

Как грамотно организовать удаление/переименование файла на Java?

Пишу десктопный хэлловорлд на JavaFX, который умеет сосать обновления с сервака и обновлять сам себя до текущей стабильной версии.

Реализовал это так:
1. Основное приложение (App.jar) проверяет, есть ли новые версии, если есть, качает новую версию себя (NewVerApp.jar) в свою корневую папку и запускает консольное приложение Uppdater.jar, которому передает свой PID. (Предполагается что запущена только одна версия приложения)
2. Uppdater.jar закрывает App.jar по его PID и пытается удалить App.jar
3. Uppdater.jar переименовывает NewVerApp.jar в App.jar
4. Uppdater.jar запускает App.jar
5. Uppdater.jar закрывается, обновление произведено успешно.

Скользкий момент в том, что когда Uppdater.jar закрывает App.jar, создается подпроцесс, который выполняется некоторое время:

/**
     * Закрывает приложение по его PID
     * @param pid
     */
    public void killAppByPID(String pid){

        Runtime r = Runtime.getRuntime();
        try {
            Process p = r.exec("taskkill /F /PID " + pid);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


Пока файл закрывается - он заблокирован (его нельзя удалить), и время блокировки больше чем p.isAlive()

Поэтому я решил удалять так:

import java.io.File;

public class RenameFileThread implements Runnable{

    private File srcFileNew, srcFileOld;
    private Thread go;

// File srcFileNew = new File("NewVerApp.jar");
// File srcFileOld  = new File("App.jar");
    RenameFileThread(File srcFileNew, File srcFileOld){

        this.srcFileNew = srcFileNew;
        this.srcFileOld = srcFileOld;

        go = new Thread(this);
        go.start();
    }

    public void run(){

        Thread th = Thread.currentThread();
        while(go == th){

           // если старый файл успешно переименован, называем новый именем старого файла
            if (srcFileOld.delete()){
                srcFileNew.renameTo(new File("App.jar"));
                this.stop();
            }
        }
        System.out.println("End of thread.");
    }
    public void stop(){ go = null; }
}


Файл удаляется в потоке, когда он успешно удален - новый файл переименовывается.
После этого производится запуск приложения:

Runtime r = Runtime.getRuntime();
        try {
            Process p = r.exec("java -jar App.jar");
        } catch (IOException e) {
            e.printStackTrace();
        }


Вопрос
Есть ли ошибки в этом подходе?
Как грамотно организовать такой процесс?
Какие еще могут быть решения?
  • Вопрос задан
  • 357 просмотров
Пригласить эксперта
Ответы на вопрос 1
@bobzer
Java EE Developer
Что такое Java Web Start:
  • Позволяет активировать приложения одним щелчком мыши
  • Обеспечивает использование новейших версий приложений
  • Устраняет необходимость проведения сложных процедур установки и обновления
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы
Bell Integrator Ульяновск
До 400 000 ₽
Bell Integrator Хабаровск
До 400 000 ₽
Bell Integrator Ижевск
До 400 000 ₽
18 апр. 2024, в 01:12
150000 руб./за проект
18 апр. 2024, в 00:10
50000 руб./за проект