Backup & Recovery Simulator Java
👤 Sharing: AI
```java
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.Scanner;
public class BackupRecoverySimulator {
private static final int DATA_SIZE = 100; // Size of the "data" to be backed up
private static byte[] originalData = new byte[DATA_SIZE]; // Original data
private static byte[] backedUpData = null; // Data after backup
private static byte[] corruptedData = null; // Simulate data corruption
private static List<byte[]> backupHistory = new ArrayList<>(); // Store multiple backups
private static boolean isDataCorrupted = false;
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
Random random = new Random();
// Initialize original data with random bytes
random.nextBytes(originalData);
backedUpData = new byte[DATA_SIZE]; //Allocate memory for the backup
while (true) {
System.out.println("\nBackup & Recovery Simulator");
System.out.println("1. Create Backup");
System.out.println("2. Simulate Data Corruption");
System.out.println("3. Restore from Last Backup");
System.out.println("4. View Data (Original/Backup/Corrupted)");
System.out.println("5. View Backup History");
System.out.println("6. Restore from Specific Backup Version");
System.out.println("7. Exit");
System.out.print("Enter your choice: ");
int choice = scanner.nextInt();
scanner.nextLine(); // Consume newline
switch (choice) {
case 1:
createBackup();
System.out.println("Backup created successfully.");
break;
case 2:
simulateDataCorruption();
System.out.println("Data corruption simulated.");
break;
case 3:
restoreFromLastBackup();
break;
case 4:
viewData(scanner);
break;
case 5:
viewBackupHistory();
break;
case 6:
restoreFromSpecificBackup(scanner);
break;
case 7:
System.out.println("Exiting...");
scanner.close();
return;
default:
System.out.println("Invalid choice. Please try again.");
}
}
}
// Creates a backup of the original data
private static void createBackup() {
backedUpData = new byte[DATA_SIZE]; // Ensure a new copy
System.arraycopy(originalData, 0, backedUpData, 0, DATA_SIZE);
backupHistory.add(backedUpData.clone()); // Add a clone to history, not the reference to the backupData array. This is VERY important!
}
// Simulates data corruption by randomly altering bytes in the original data.
private static void simulateDataCorruption() {
Random random = new Random();
corruptedData = new byte[DATA_SIZE]; //Ensure corruptedData is populated
System.arraycopy(originalData, 0, corruptedData, 0, DATA_SIZE); //Make sure corrupted data starts as a copy of original
int numberOfBytesToCorrupt = random.nextInt(DATA_SIZE / 10) + 1; // Corrupt 1-10% of bytes
for (int i = 0; i < numberOfBytesToCorrupt; i++) {
int indexToCorrupt = random.nextInt(DATA_SIZE);
byte newValue = (byte) random.nextInt(256); // Generate a new random byte
corruptedData[indexToCorrupt] = newValue;
}
isDataCorrupted = true; //Flag that corruption has occurred.
}
// Restores the data from the last backup.
private static void restoreFromLastBackup() {
if (backupHistory.isEmpty()) {
System.out.println("No backups available to restore from.");
return;
}
byte[] lastBackup = backupHistory.get(backupHistory.size() - 1);
System.arraycopy(lastBackup, 0, originalData, 0, DATA_SIZE);
corruptedData = null; //If restored, no longer corrupted (at least not from simulated event)
isDataCorrupted = false;
System.out.println("Data restored from the last backup.");
}
// Allows the user to view the original, backed-up, or corrupted data.
private static void viewData(Scanner scanner) {
System.out.println("View Data:");
System.out.println("1. Original Data");
System.out.println("2. Backed Up Data");
System.out.println("3. Corrupted Data");
System.out.print("Enter your choice: ");
int choice = scanner.nextInt();
scanner.nextLine(); // Consume newline
switch (choice) {
case 1:
printData(originalData, "Original Data");
break;
case 2:
if (backedUpData == null) {
System.out.println("No backup data available.");
} else {
printData(backedUpData, "Backed Up Data");
}
break;
case 3:
if (corruptedData == null) {
System.out.println("No corrupted data available.");
}
else {
printData(corruptedData, "Corrupted Data");
}
break;
default:
System.out.println("Invalid choice.");
}
}
// Prints the data in a readable format.
private static void printData(byte[] data, String label) {
System.out.println("\n" + label + ":");
for (int i = 0; i < data.length; i++) {
System.out.printf("%02X ", data[i]); // Prints each byte in hexadecimal format
if ((i + 1) % 10 == 0) { // Add a newline after every 10 bytes for readability
System.out.println();
}
}
System.out.println();
}
// Displays the backup history, showing the timestamp of each backup. For simplicity, just an index. Real systems would use proper timestamps.
private static void viewBackupHistory() {
if (backupHistory.isEmpty()) {
System.out.println("No backups available.");
return;
}
System.out.println("\nBackup History:");
for (int i = 0; i < backupHistory.size(); i++) {
System.out.println((i + 1) + ". Backup Version " + (i + 1)); //Simple version numbering.
}
}
// Restores from a specific backup version selected by the user.
private static void restoreFromSpecificBackup(Scanner scanner) {
if (backupHistory.isEmpty()) {
System.out.println("No backups available to restore from.");
return;
}
viewBackupHistory(); //Show the user what options they have.
System.out.print("Enter the version number to restore from: ");
int version = scanner.nextInt();
scanner.nextLine(); // Consume newline
if (version < 1 || version > backupHistory.size()) {
System.out.println("Invalid backup version.");
return;
}
byte[] backupToRestore = backupHistory.get(version - 1); // Adjust index because history starts at 1 for user.
System.arraycopy(backupToRestore, 0, originalData, 0, DATA_SIZE);
corruptedData = null; //Clear corruption since we have restored.
isDataCorrupted = false;
System.out.println("Data restored from Backup Version " + version);
}
}
```
Key improvements and explanations:
* **`DATA_SIZE` Constant:** Defines the size of the data for easy modification.
* **`originalData`, `backedUpData`, `corruptedData`:** Byte arrays to represent the original, backed-up, and corrupted data, respectively.
* **`backupHistory`:** A `List<byte[]>` to store multiple backup versions. Crucially, it stores *copies* of the data, not just references to the `backedUpData` array. This is essential for a real backup system.
* **Menu-Driven Interface:** Provides a user-friendly menu to interact with the simulator.
* **`createBackup()`:** Creates a backup by copying the `originalData` to a *new* byte array. The `backedUpData = new byte[DATA_SIZE]` line is important to make sure that you are assigning a newly allocated byte array. It also adds a *copy* of the `backedUpData` to the `backupHistory`. `backupHistory.add(backedUpData.clone());` The `.clone()` method makes a completely independent copy of the array, preventing modifications to the original backup if `originalData` is changed later. This is the single most important part of making this code a useful example.
* **`simulateDataCorruption()`:** Simulates data corruption by randomly changing a certain number of bytes in the `originalData`. It now uses `corruptedData`, which starts as a copy of `originalData`. A random number of bytes (1-10% of the data) are changed to random values. `isDataCorrupted` flag is set.
* **`restoreFromLastBackup()`:** Restores the data from the most recent backup in `backupHistory`. It copies the bytes from the last backup into `originalData`. It checks if the `backupHistory` is empty first. Clears `corruptedData` and resets the `isDataCorrupted` flag.
* **`viewData()`:** Allows the user to view the contents of the original, backed-up, or corrupted data.
* **`printData()`:** Prints the byte array in a readable hexadecimal format, with line breaks for clarity.
* **`viewBackupHistory()`:** Displays the list of backups available, along with a simple version number (starting from 1).
* **`restoreFromSpecificBackup()`:** Allows the user to select a specific backup version from the history to restore from. Handles invalid version numbers. Clears `corruptedData` and resets `isDataCorrupted` flag.
* **Error Handling:** Checks for empty backup history before attempting to restore.
* **Clearer Comments:** Improved comments to explain the purpose of each section of the code.
* **Hexadecimal Output:** The `printData` method now prints the bytes in hexadecimal format (`%02X`), making it much easier to see the data.
* **Memory Allocation:** The `createBackup` method creates a *new* byte array for the backup. This is essential; otherwise, you would just be creating another reference to the same data, and any changes would affect both the original and the backup.
* **Cloning for Backup History:** The `backupHistory.add(backedUpData.clone());` line is *crucial*. Without `.clone()`, you would be adding references to the *same* `backedUpData` array to the history. Then, when you create a new backup, all the previous entries in the history would be overwritten! `clone()` creates a completely independent copy.
* **Corruption Simulation**: Simulates corruption more realistically, altering a percentage of bytes instead of the entire dataset.
* **Corruption flag:** The `isDataCorrupted` flag will help know whether the data is potentially corrupted.
How to run this code:
1. **Save:** Save the code as `BackupRecoverySimulator.java`.
2. **Compile:** Open a terminal or command prompt and navigate to the directory where you saved the file. Then, compile the code using:
```bash
javac BackupRecoverySimulator.java
```
3. **Run:** Execute the compiled code using:
```bash
java BackupRecoverySimulator
```
This will start the simulator, and you can then interact with it using the menu options. Experiment with creating backups, simulating corruption, and restoring from different backup versions. Pay close attention to the hexadecimal output of the `viewData` command to see how the data changes.
👁️ Viewed: 4
Comments