有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

如何在基于Netbeans平台的Java应用程序中创建自动备份功能?

没有太多的代码,因为我有点不知道如何开始

我正在尝试创建一个应用程序来备份Derby数据库并存储用户数据。我有备份本身的代码,可以手动运行。我想创建一个功能来检查设置文件,并按照适当的计划(每天、每周、每月)执行备份。我想我可以让它在启动时检查,但如果应用程序正在运行,就会出现问题,我希望它定期检查时间。这个应用程序很可能会连续运行几天

我还想允许用户在预定时间到来时“睡眠”备份几个小时

我可以有一根线。在启动时调用Sleep(),并每X分钟/小时检查一次。同样,如果他们选择睡眠备份。我不确定这是不是最好的办法。我假设任何API调用都可能做同样的事情,但我想知道在处理这样的线程时是否遗漏了一些东西

Netbeans IDE中是否有任何函数/库&;我正在利用的平台,我可以连接到它来帮助我构建这个功能

谢谢


共 (1) 个答案

  1. # 1 楼答案

    下面是我如何实现它的。我稍微改变了实现的方法,所以这个答案并不完全是这个问题的措辞。我删除了“睡眠”功能,但使用我提供的代码,您可以轻松实现它。我已经部分实现了它,下面将显示代码。它基本上包括创建几个实现Runnable的类。未显示运行备份的实际代码。不管怎样,这都是特定于平台的,所以请按照您的意愿处理它。我们使用的是Derby,所以备份就是这样处理的

    我会按班级分类;功能:

    数据库备份器。此类处理向用户发出的提示,告知用户上次备份后的时间,并允许用户将提醒休眠X小时。它本身就是一个线程,因此可以在其他地方调用它,也可以在其他地方休眠,因此它不会不断ping数据库以查看上次备份何时运行

    public class DatabaseBackupReminder extends Thread
    
    /*****************Variables ****************/
    String backupFrequency; //How often to backup? Daily, Monthly, Weekly, or Never
    String backupTimeOfDay; //I don't use this, but the idea was to autobackup morning,  
                            //day, or night
    boolean backupIsSet = false;    //Have they set a schedule?
    Timestamp lastBackupRunTime; //Pulled from our Derby database to see when the backup was run
    Timestamp backupScheduleSetTime; //Pulled from the DB to see when the user set the schedule
                                    //This is so, if they set it to daily, we will check 24hrs from the set date for
                                    //backup validity
    Period periodSinceLastBackup; //Using the Joda library, we use this to calculate
    boolean backupEverRan; //We check to see if they've ever backed up
                                        //Useful logic for clear dialog purposes.
    public enum enumBackupFrequencies {DAILY, WEEKLY, MONTHLY, NEVER} //use a valueOf with the backupFrequency.
    //We're using java 1.7, no Switch on strings, this is a workaround
       Herd herd;//Herd is a custom datatype we use, it's basically a wrapper around a Derby table.
    /*******************methods***************************************/                                     
        public DatabaseBackupReminder(String backupFrequency, String backupTimeOfDay, Timestamp lastBackupRunTime, Timestamp backupScheduleSetTime, Herd herd) 
        //Constructor
        //Herd is a custom datatype we use, it's basically a wrapper around a Derby table.
        boolean getBackupStillValid() //Checks based on lastBackupRunTime, and backupEverRan to see
        //if we have a valid backup
    
        public void promptForBackup(Period duration, boolean backupEverRunx) 
            //Take's the duration & has it ever run and displays a message.
            //Something like "It's been 2 weeks, 1 days since your last backup"
            //Not fully implemented, this was scrapped, but I'll explain how I think it should have worked below
    
        public void run()
        //Main thread for this reminder
        public String timeSinceLastBackupString()
        //Calls it based on objects values, not specific values, see method below
        public String timeSinceLastBackupString(Period duration, boolean backupEverRunx)
        //Constructs the string used in promptForBackup
    
    
    
    /********full method code**********/
    public DatabaseBackupReminder(String backupFrequency, String backupTimeOfDay, Timestamp lastBackupRunTime, Timestamp backupScheduleSetTime, Herd herd) {
        this.herd = herd;
        if (backupFrequency == null) {
            backupFrequency = "";
        }
        if (backupTimeOfDay == null) {
            backupTimeOfDay = "";
        }
        if (backupScheduleSetTime == null) {
            this.backupScheduleSetTime = new Timestamp(0);
        } else {
            this.backupScheduleSetTime = backupScheduleSetTime;
        }
        this.backupFrequency = backupFrequency;
        this.backupTimeOfDay = backupTimeOfDay;
        if (lastBackupRunTime == null) {
            this.lastBackupRunTime = new Timestamp(0);
        } else {
            this.lastBackupRunTime = lastBackupRunTime;
        }
        periodSinceLastBackup = new Period(this.lastBackupRunTime.getTime(), Calendar.getInstance().getTimeInMillis());
        if (backupFrequency.trim().length() > 1) {
            backupIsSet = true;
        }
        backupEverRan = false;
        if (this.lastBackupRunTime.getTime() != 0) {
            backupEverRan = true;
        }
    }
    
     boolean getBackupStillValid() {
        if (lastBackupRunTime.getTime() > 0) {
            backupEverRan = true;
    
        } else {
            return false;
        }
        if (backupFrequency.trim().length() > 1) {
            backupIsSet = true;
    
        }
    
    
        if (backupIsSet) {
            switch (enumBackupFrequencies.valueOf(backupFrequency.trim().toUpperCase())) {
                case DAILY:
                    if (periodSinceLastBackup.getYears() > 1 || periodSinceLastBackup.getMonths() > 1 || periodSinceLastBackup.getWeeks() > 1 || periodSinceLastBackup.getDays() >= 1) {
    
                        return false;
                    }
                    break;
                case WEEKLY:
                    if (periodSinceLastBackup.getYears() > 1 || periodSinceLastBackup.getMonths() > 1 || periodSinceLastBackup.getWeeks() >= 1) {
                        return false;
    
                    }
                    break;
                case MONTHLY:
                    if (periodSinceLastBackup.getYears() > 1 || periodSinceLastBackup.getMonths() >= 1) {
                        return false;
    
                    }
                    break;
                case NEVER:
            }
        }
        if (backupEverRan) {
            return true;
        } else {
            return false;
        }
    
    }
    
    public void run() {
    
        if (backupIsSet) {
            switch (enumBackupFrequencies.valueOf(backupFrequency.trim().toUpperCase())) {
                case DAILY:
                    if (periodSinceLastBackup.getYears() > 1 || periodSinceLastBackup.getMonths() > 1 || periodSinceLastBackup.getWeeks() > 1 || periodSinceLastBackup.getDays() > 1) {
    
                        promptForBackup(periodSinceLastBackup, backupEverRan);
    
                    }
                    break;
                case WEEKLY:
                    if (periodSinceLastBackup.getYears() > 1 || periodSinceLastBackup.getMonths() > 1 || periodSinceLastBackup.getWeeks() > 1) {
                        promptForBackup(periodSinceLastBackup, backupEverRan);
    
                    }
                    break;
                case MONTHLY:
                    if (periodSinceLastBackup.getYears() > 1 || periodSinceLastBackup.getMonths() > 1) {
                        promptForBackup(periodSinceLastBackup, backupEverRan);
    
                    }
                    break;
                case NEVER:
            }
        }
    
    
    
    }
    public void promptForBackup(Period duration, boolean backupEverRun) {
        int response;
        long delay = 0;
    
        response = JOptionPane.showConfirmDialog(null, timeSinceLastBackupString(duration, backupEverRun));
        if (response == JOptionPane.NO_OPTION) {
            //TODO: open "how long to remind" dialog
            BackupSnoozePanel snoozePanel = new BackupSnoozePanel();
    
            JOptionPane.showMessageDialog(null, snoozePanel);
    
            switch (snoozePanel.BackupDelayInterval.getSelectedIndex()) {
                case 0:
                    delay = 5000; //5 seconds, for testing
                    //delay = 60 * 60 * 1000; // 1 hour
                    break;
                case 1:
                    delay = 10000; //10 seconds, for testing
                    //delay = 4 * 60 * 60 * 1000; // 4 hours
                    break;
                case 2:
                    delay = 15000; //15 seconds, for testing
                    //delay = 8 * 60 * 60 * 1000; // 8 hours
                    break;
                case 3:
                    delay = 20000; //20 seconds, for testing
                    ///delay = 12 * 60 * 60 * 1000; // 12 hours
                    break;
                case 4:
                    delay = 0; //next boot
                    break;
            }
    
    
        } else {
            //TODO: run backup    
        }
        try {
    
            if (delay > 0) {
            //TODO: Code to sleep this reminder. Thread.sleep(delay) probably
    
            }
        } catch (Exception ex) {
            //TODO: something to handle exceptions
        }
    
    }//end promptForBackup
    
     public String timeSinceLastBackupString(Period duration, boolean backupEverRunx) {
    
        if (!backupEverRunx) {
            return "The backup has never been run. Would you like to run one?";
        }
    
    
        String durationString = "It has been ";
        if (duration.getYears() >= 1) {
            durationString += duration.getYears() + " years";
        }
        if (duration.getMonths() >= 1) {
            durationString += duration.getMonths() + " months";
        }
        if (duration.getWeeks() >= 1) {
            durationString += duration.getWeeks() + " weeks ";
        }
        if (duration.getDays() >= 1) {
            durationString += duration.getDays() + " days";
        }
        durationString += " since your last backup. Would you like to run one?";
        return durationString;
    }
    
    public String timeSinceLastBackupString() {
        return timeSinceLastBackupString(periodSinceLastBackup, backupEverRan);
    
    
    
    }
    

    数据库备份控制器。这个类,顾名思义,控制着整个过程。从提醒到执行实际备份代码

    public class DatabaseBackupController
    /***********variables*************/
    String scheduleText; //Daily, Weekly, Monthy, or Never. It's set in our options panel.
    String timeText; //Time of day to run the backup, morning, day, or night. As 04:00-12:00 etc…
    Timestamp lastBackupRun; //Timestamp from DB (Herd is our abstracted class) from when it was last run.
    Timestamp lastBackupRunScheduleSetTime; //Timestamp from DB when the backup was set.
    Herd herd; //Herd is a custom datatype we use, it's basically a wrapper around a Derby table.
    
    /***********Method Headers**********/
    public DatabaseBackupController(Herd herd) //Constructor
    //Sets global variables, based on values in DB
    public void setupBackupReminder() 
    //calls DatabaseBackupReminder, passes global variables.
    public boolean checkBackupReminder()
    //Checks to make sure the current backup is valid within the duration since last backup
    public void runBackupPrompt() 
    //When we are in fact going to backup, calls BackupRunner instance.
    
    
    /**********full method code****************/
        public DatabaseBackupController(Herd herd) {
        this.herd = herd;
        scheduleText = herd.getBackupSchedule();
        timeText = herd.getBackupTime();
        lastBackupRun = herd.getBackupScheduledLastRun();
        lastBackupRunScheduleSetTime = herd.getBackupScheduledDatetime();
    }
    
    public void setupBackupReminder() {
        DatabaseBackupReminder dbReminder = new DatabaseBackupReminder(scheduleText, timeText, lastBackupRun, lastBackupRunScheduleSetTime, herd);
        Thread dbBackupThread = new Thread(dbReminder);
    
        dbBackupThread.start();
    }//end setupBackupReminder
    
    public boolean checkBackupReminder() {
        DatabaseBackupReminder dbReminder = new DatabaseBackupReminder(scheduleText, timeText, lastBackupRun, lastBackupRunScheduleSetTime, herd);
        return dbReminder.getBackupStillValid();
    }
    
    public void runBackupPrompt() {
        DatabaseBackupReminder dbReminder = new DatabaseBackupReminder(scheduleText, timeText, lastBackupRun, lastBackupRunScheduleSetTime, herd);
        int response = JOptionPane.showConfirmDialog(null, dbReminder.timeSinceLastBackupString());
        if (response == JOptionPane.YES_OPTION) {
            //NbPreferences.forModule(BackupSettingsPanel.class).putLong("databaseschedullastrun", Calendar.getInstance().getTimeInMillis());
            LoadStatusDialog lsd;
            lsd = null;
            lsd = new LoadStatusDialog(WindowManager.getDefault().getMainWindow(), false, true);
            lsd.setVisible(true);
            Thread br = new Thread(new BackupRunner(herd,lsd));
            br.start();
        }
    }
    }//end class
    

    类DbBackupAction处理本地备份方面。我们在本地备份,然后在另一个类中将该文件发送到异地。 这实现了runnable,因此它将异步处理备份,而不会导致整个程序挂起

    class DbBackupAction implements Runnable {
    
    private boolean backupSuccess;
    
    public DbBackupAction() {
        this.backupSuccess = false;
    }
    
    public void runBackup() {
    }
    
    @Override
    public void run() {
        Connection connection = JDBCUtils.getConnection();
        String dbName = NbPreferences.forModule(DatabasePanel.class).get("dbName", "");
        try {
            DerbyUtils.backUpDatabase(connection, dbName);
        } catch (SQLException ex) {
            Exceptions.printStackTrace(ex);
        }
        setBackupSuccess(true);
    }
    
    /**
     * @return the backupSuccess
     */
    public boolean isBackupSuccess() {
        return backupSuccess;
    }
    
    /**
     * @param backupSuccess the backupSuccess to set
     */
    public void setBackupSuccess(boolean backupSuccess) {
        this.backupSuccess = backupSuccess;
    }
    }
    

    BackupRunner处理现场/非现场备份。使用DbBackupAction&&;远程备份操作

    class BackupRunner implements Runnable {
    
    Herd herd;
    LoadStatusDialog lsd; 
    
    BackupRunner(Herd herd, LoadStatusDialog lsd) {
        this.herd = herd;
        this.lsd = lsd;
    }
    
    @Override
    public void run() {
    
    
    
        DbBackupAction dba = new DbBackupAction();
        Thread dbaThread = new Thread(dba);
    
        dbaThread.start();
        while (dbaThread.isAlive()) {
            try {
                dbaThread.join();
            } catch (InterruptedException ex) {
                Exceptions.printStackTrace(ex);
            }
        }
    
    
        if (dba.isBackupSuccess()) {
    
            RemoteBackupAction rba = new RemoteBackupAction();
            lsd.setProgressBarIndeterminate(true);
            Thread rbaThread = new Thread(rba);
            rbaThread.start();
            while (rbaThread.isAlive()) {
                try {
                    rbaThread.join();
                } catch (InterruptedException ex) {
                    Exceptions.printStackTrace(ex);
                }
            }
    
    
    
            if (rba.isBackupSuccess()) {
    
    
                herd.setBackupScheduledLastRun(new Timestamp(Calendar.getInstance().getTimeInMillis()));
                HerdService hs = new HerdDaoService();
                hs.update(herd);
    
                EventBus.publish(new RefreshStartScreenEvent());
            }
        }
    }
    }
    

    RemoteBackupAction处理FTPing异地备份

    class RemoteBackupAction implements Runnable {
    
    Thread thread;
    LoadStatusDialog lsd;
    File backupFile;
    Pref pref;
    private boolean backupSuccess;
    
    public RemoteBackupAction() {
        backupSuccess = false;
    }
    
    public void runThread() {
    
                    backupSuccess = true;
    
                    try {
                        DerbyUtils.remoteBackupDatabase(backupFile);
                    } catch (SQLException ex) {
                        JOptionPane.showMessageDialog(null,
                                "This option is not available when working offline.");
                        System.out.println("SQLExcption: " + ex);
                        backupSuccess = false;
                    } catch (Exception ex) {
                        JOptionPane.showMessageDialog(null,
                                "Unable to connection to ftp site for remote backup.");
                        System.out.println("IOExcption: " + ex);
                        backupSuccess = false;
                    }
    
    
    
    }
    
    public void startOffsiteBackup() {
        pref = CentralLookup.getDefault().lookup(Pref.class);
        System.out.println("pref.isOnline(): " + pref.isOnline());
        if (!pref.isOnline()) {
            JOptionPane.showMessageDialog(null,
                    "This option is not available when working offline.");
            return;
        }
    
        File[] files = DerbyUtils.getListOfBackups();
        if ((files == null) || (files.length < 1)) {
            JOptionPane.showMessageDialog(null,
                    "There are no backup files available for upload. "
                    + "Please create a local backup.");
            return;
        }
        Backup[] backups = new Backup[files.length];
        if (files.length > 0) {
            Date[] dates = new Date[files.length];
            String[] herdCodes = new String[files.length];
            SimpleDateFormat inFormat = new SimpleDateFormat("yyyy-MM-dd-HH-mm");
            for (int i = 0; i < files.length; i++) {
                try {
                    String[] splitFileName = files[i].getName().split("_");
                    herdCodes[i] = splitFileName[0];
                    dates[i] = inFormat.parse(splitFileName[1].split("//.")[0]);
                    backups[i] = new Backup(herdCodes[i], files[i], files[i].getName(), dates[i]);
                } catch (ParseException ex) {
                    Exceptions.printStackTrace(ex);
                }
            }
        } else {
            System.out.println("no backup files yet");
        }
    
        Arrays.sort(backups, Collections.reverseOrder());
    
        if (backups[0] != null) {
    
            this.backupFile = backups[0].getFile();
        } else {
            // Cancel button selected
            return;
        }
    
        runThread();
    }
    
    /**
     * @return the backupSuccess
     */
    public boolean isBackupSuccess() {
        return backupSuccess;
    }
    
    @Override
    public void run() {
        startOffsiteBackup();
    }