簡體   English   中英

如何在基於Netbeans平台的Java應用程序中創建自動備份功能?

[英]How do I create an auto backup feature in my Netbeans platform based Java application?

沒有太多代碼,因為我對如何啟動有點不知所措。

我正在嘗試創建一個備份Derby數據庫並存儲用戶數據的應用程序。 我有可以手動運行的備份代碼。 我想創建一個功能來檢查設置文件,並按適當的時間表(每天,每周,每月)執行備份。 我認為可以在啟動時進行檢查,但是如果應用程序正在運行,則存在一個問題,我希望它能夠定期檢查時間。 此應用程序很有可能會連續運行幾天。

如果計划的時間到了,我還希望允許用戶將備份“休眠”幾個小時。

我可以在啟動時調用Thread.Sleep(),並每隔X分鍾/小時檢查一次。 同樣,如果他們選擇休眠備份。 我不確定這是否是最好的方法。 我假設任何API調用都可能會執行相同的操作,但是我想知道在處理這樣的線程時是否丟失了某些東西。

我可以利用Netbeans IDE和平台中的任何功能/庫,以幫助我構建此功能嗎?

謝謝

這是我的實現方式。 我稍微改變了實現方法,所以這個答案並不完全是問題的措辭。 我刪除了“睡眠”功能,但是使用我提供的代碼可以輕松實現它。 我已經部分實現了,下面將顯示代碼。 它基本上涉及創建一些實現Runnable的類。 沒有顯示運行備份的實際代碼。 無論如何,那將是特定於平台的,因此請按需處理。 我們正在使用Derby,所以這就是我們備份的處理方式。

我將按類和功能對其進行細分:

DatabaseBackupReminder。 此類處理向用戶顯示的提示,告訴他們自上次備份以來已經過了多長時間,並允許他們將提醒睡眠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);



}

DatabaseBackupController。 顧名思義,此類控制着整個過程。 從提醒到執行實際的備份代碼。

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處理本地備份方面。 我們在本地備份,然后將該文件發送到另一個班級之外。 這實現了可運行的,因此它將異步處理備份,並且不會導致整個程序掛斷。

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 && RemoteBackupAction

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處理FTP異地備份。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM