import java.io.*;
import java.util.*;

/**
 * FileManagementSystem - Simulates OS file management operations
 * Handles file fragment collection, memory space calculation, and transfer simulation
 * 
 * @author College Student
 * @version 2.0
 * @date 2026-07-05
 */
class FileManagementSystem {
    
    // File properties
    private int fileSize;               // Total file size in KB
    private int diskBlockSize;          // Size of each disk block in KB
    private int[] allocatedBlocks;      // Disk block numbers allocated to the file
    private int transferStartTime;      // Time interval when transfer begins
    private int transferEndTime;        // Time interval when transfer ends
    private String fileName;            // Name of the file
    
    // Job scheduling data structure
    private ArrayList<Job> jobs;
    
    /**
     * Constructor initializes the file management system with file properties
     * 
     * @param fileName Name of the file
     * @param fileSize Total file size in KB
     * @param diskBlockSize Size of each disk block in KB
     * @param allocatedBlocks Array of disk block numbers
     * @param transferStartTime Time interval to start memory transfer
     * @param transferEndTime Time interval to end memory transfer
     */
    public FileManagementSystem(String fileName, int fileSize, int diskBlockSize, 
                               int[] allocatedBlocks, int transferStartTime, 
                               int transferEndTime) {
        this.fileName = fileName;
        this.fileSize = fileSize;
        this.diskBlockSize = diskBlockSize;
        this.allocatedBlocks = Arrays.copyOf(allocatedBlocks, allocatedBlocks.length);
        this.transferStartTime = transferStartTime;
        this.transferEndTime = transferEndTime;
        this.jobs = new ArrayList<Job>();
    }
    
    /**
     * Getter method for allocated blocks
     * 
     * @return Array of allocated disk blocks
     */
    public int[] getAllocatedBlocks() {
        return Arrays.copyOf(allocatedBlocks, allocatedBlocks.length);
    }
    
    /**
     * Getter method for number of allocated blocks
     * 
     * @return Number of allocated blocks
     */
    public int getAllocatedBlockCount() {
        return allocatedBlocks.length;
    }
    
    /**
     * Calculates the total number of disk blocks needed for the file
     * Based on file size and disk block size
     * 
     * @return Number of disk blocks required
     */
    public int calculateRequiredBlocks() {
        // Calculate blocks needed (ceil division)
        int requiredBlocks = (int) Math.ceil((double) fileSize / diskBlockSize);
        return requiredBlocks;
    }
    
    /**
     * Collects information about all file fragments from disk
     * Verifies if the allocated blocks match the required number
     * 
     * @return HashMap containing fragment information
     */
    public HashMap<String, Object> collectFragmentInformation() {
        HashMap<String, Object> fragmentInfo = new HashMap<String, Object>();
        int requiredBlocks = calculateRequiredBlocks();
        int actualBlocks = allocatedBlocks.length;
        
        // Store fragment information
        fragmentInfo.put("fileName", fileName);
        fragmentInfo.put("totalFileSize", fileSize);
        fragmentInfo.put("diskBlockSize", diskBlockSize);
        fragmentInfo.put("requiredBlocks", requiredBlocks);
        fragmentInfo.put("allocatedBlocks", allocatedBlocks);
        fragmentInfo.put("actualBlocks", actualBlocks);
        
        // Check if allocation is sufficient
        boolean sufficientAllocation = (actualBlocks >= requiredBlocks);
        fragmentInfo.put("sufficientAllocation", sufficientAllocation);
        
        // Calculate total allocated space
        int totalAllocatedSpace = actualBlocks * diskBlockSize;
        fragmentInfo.put("totalAllocatedSpace", totalAllocatedSpace);
        
        // Calculate wasted space (or deficit)
        int spaceDifference = totalAllocatedSpace - fileSize;
        fragmentInfo.put("spaceDifference", spaceDifference);
        
        // Display allocated blocks with their positions
        StringBuilder blockDetails = new StringBuilder();
        for (int i = 0; i < allocatedBlocks.length; i++) {
            blockDetails.append("Block ").append(i+1).append(": Disk Block ").append(allocatedBlocks[i]);
            if (i < allocatedBlocks.length - 1) {
                blockDetails.append(", ");
            }
        }
        fragmentInfo.put("blockDetails", blockDetails.toString());
        
        return fragmentInfo;
    }
    
    /**
     * Calculates the memory space required to store the file
     * For simplicity, this equals the total file size
     * 
     * @return Memory space required in KB
     */
    public int calculateMemorySpace() {
        // As specified, memory space equals total file size
        return fileSize;
    }
    
    /**
     * Adds a job to the scheduling queue
     * 
     * @param jobId Unique identifier for the job
     * @param startTime Time interval when job starts
     * @param requiredSize Memory required for the job
     * @param executionInterval Duration of execution
     */
    public void addJob(int jobId, int startTime, int requiredSize, int executionInterval) {
        Job newJob = new Job(jobId, startTime, requiredSize, executionInterval);
        jobs.add(newJob);
        System.out.println("Job " + jobId + " added: Starts at interval " + startTime + 
                          ", Size = " + requiredSize + " KB, Duration = " + executionInterval + " intervals");
    }
    
    /**
     * Simulates the file transfer to memory based on job scheduling
     * Checks if the file can be transferred during the specified interval
     * 
     * @return String result of the transfer simulation
     */
    public String simulateFileTransfer() {
        int memorySpace = calculateMemorySpace();
        boolean canTransfer = false;
        String result = "";
        Job selectedJob = null;
        
        System.out.println("\n--- Transfer Simulation Details ---");
        System.out.println("File: " + fileName + " needs " + memorySpace + " KB of memory");
        System.out.println("Transfer window: Interval " + transferStartTime + " to " + transferEndTime);
        System.out.println("Checking available jobs...");
        
        // Check if any job has enough memory space during the transfer interval
        for (Job job : jobs) {
            int jobStart = job.getStartTime();
            int jobEnd = jobStart + job.getExecutionInterval();
            int jobMemory = job.getRequiredSize();
            
            System.out.println("Job " + job.getJobId() + ": Runs from " + jobStart + " to " + jobEnd + 
                              ", Has " + jobMemory + " KB memory available");
            
            // Check if job covers the transfer window
            if (jobStart <= transferStartTime && jobEnd >= transferEndTime) {
                System.out.println("  -> Covers the transfer window!");
                if (jobMemory >= memorySpace) {
                    canTransfer = true;
                    selectedJob = job;
                    System.out.println("  -> Has enough memory! Transfer possible.");
                    break;
                } else {
                    System.out.println("  -> Not enough memory. Needs " + memorySpace + " KB but only has " + jobMemory + " KB");
                }
            } else {
                System.out.println("  -> Does not cover the transfer window");
            }
        }
        
        if (canTransfer && selectedJob != null) {
            result = "SUCCESS: File transfer completed during interval " + 
                     transferStartTime + " to " + transferEndTime +
                     " using Job " + selectedJob.getJobId() + 
                     " which had " + selectedJob.getRequiredSize() + " KB available";
        } else {
            result = "FAILED: File transfer could not complete during interval " +
                     transferStartTime + " to " + transferEndTime + 
                     ". Insufficient memory or no job available during the window.";
        }
        
        return result;
    }
    
    /**
     * Displays all file information in a formatted manner
     */
    public void displayFileInfo() {
        System.out.println("\n========== FILE INFORMATION ==========");
        System.out.println("File Name: " + fileName);
        System.out.println("File Size: " + fileSize + " KB");
        System.out.println("Disk Block Size: " + diskBlockSize + " KB");
        System.out.println("Allocated Disk Blocks: " + Arrays.toString(allocatedBlocks));
        System.out.println("Transfer Interval: " + transferStartTime + " to " + transferEndTime);
        
        HashMap<String, Object> fragmentInfo = collectFragmentInformation();
        System.out.println("\n-------- FRAGMENT INFORMATION --------");
        System.out.println("Required Blocks: " + fragmentInfo.get("requiredBlocks"));
        System.out.println("Actual Allocated Blocks: " + fragmentInfo.get("actualBlocks"));
        System.out.println("Total Allocated Space: " + fragmentInfo.get("totalAllocatedSpace") + " KB");
        System.out.println("Space Difference: " + fragmentInfo.get("spaceDifference") + " KB");
        System.out.println("Sufficient Allocation: " + fragmentInfo.get("sufficientAllocation"));
        System.out.println("Block Details: " + fragmentInfo.get("blockDetails"));
        
        System.out.println("\n--------- MEMORY REQUIREMENTS ---------");
        System.out.println("Memory Space Required: " + calculateMemorySpace() + " KB");
        System.out.println("=======================================");
    }
    
    /**
     * Displays all jobs in the system
     */
    public void displayAllJobs() {
        System.out.println("\n========== JOB SCHEDULE ==========");
        System.out.println("Job ID | Start Time | Size (KB) | Duration | End Time");
        System.out.println("-----------------------------------------------------");
        for (Job job : jobs) {
            int endTime = job.getStartTime() + job.getExecutionInterval();
            System.out.printf("  %-5d |    %-8d |    %-7d |   %-7d |    %-7d%n",
                job.getJobId(), job.getStartTime(), job.getRequiredSize(), 
                job.getExecutionInterval(), endTime);
        }
        System.out.println("===================================");
    }
    
    /**
     * Inner class representing a Job in the system
     */
    private class Job {
        private int jobId;
        private int startTime;
        private int requiredSize;
        private int executionInterval;
        
        /**
         * Constructor for Job
         * 
         * @param jobId Unique identifier
         * @param startTime Time interval when job starts
         * @param requiredSize Memory required
         * @param executionInterval Duration of execution
         */
        public Job(int jobId, int startTime, int requiredSize, int executionInterval) {
            this.jobId = jobId;
            this.startTime = startTime;
            this.requiredSize = requiredSize;
            this.executionInterval = executionInterval;
        }
        
        public int getJobId() { return jobId; }
        public int getStartTime() { return startTime; }
        public int getRequiredSize() { return requiredSize; }
        public int getExecutionInterval() { return executionInterval; }
    }
}

/**
 * Main class - Entry point for the program
 */
public class Main {
    /**
     * Main method for testing the FileManagementSystem
     * Tests with the specified file and job data
     */
    public static void main(String[] args) {
        System.out.println("==========================================================");
        System.out.println("   OPERATING SYSTEMS FILE MANAGEMENT SIMULATION");
        System.out.println("==========================================================\n");
        
        // ============================================================
        // TEST 1: SPECIFIED FILE FROM THE ASSIGNMENT
        // ============================================================
        System.out.println("TEST 1: SPECIFIED FILE FROM ASSIGNMENT\n");
        System.out.println("File: 8KB file, 1KB block size, allocated blocks: 28,5,12,13,1,4");
        System.out.println("Transfer: Interval 12 to 16\n");
        
        // Create file management system with specified parameters
        String fileName = "AssignmentFile.txt";
        int fileSize = 8;           // 8 KB
        int diskBlockSize = 1;      // 1 KB
        int[] allocatedBlocks = {28, 5, 12, 13, 1, 4};
        int transferStartTime = 12;
        int transferEndTime = 16;
        
        FileManagementSystem fms = new FileManagementSystem(
            fileName, fileSize, diskBlockSize, allocatedBlocks, 
            transferStartTime, transferEndTime
        );
        
        // Add jobs from the specified table
        fms.addJob(1, 1, 2, 7);   // Job 1: Start 1, Size 2, Interval 7
        fms.addJob(2, 2, 3, 8);   // Job 2: Start 2, Size 3, Interval 8
        fms.addJob(3, 3, 4, 6);   // Job 3: Start 3, Size 4, Interval 6
        fms.addJob(4, 4, 3, 6);   // Job 4: Start 4, Size 3, Interval 6
        fms.addJob(5, 5, 2, 9);   // Job 5: Start 5, Size 2, Interval 9
        fms.addJob(6, 6, 3, 6);   // Job 6: Start 6, Size 3, Interval 6
        fms.addJob(7, 7, 2, 6);   // Job 7: Start 7, Size 2, Interval 6
        
        // Display file information
        fms.displayFileInfo();
        fms.displayAllJobs();
        
        // Run the transfer simulation
        System.out.println("\n" + fms.simulateFileTransfer());
        
        // ============================================================
        // TEST 2: SUFFICIENT BLOCK ALLOCATION
        // ============================================================
        System.out.println("\n\n" + "=".repeat(58));
        System.out.println("TEST 2: SUFFICIENT BLOCK ALLOCATION");
        System.out.println("=".repeat(58) + "\n");
        
        int[] testBlocks2 = {10, 15, 20, 25, 30, 35, 40, 45}; // 8 blocks for 8KB file
        FileManagementSystem fms2 = new FileManagementSystem(
            "TestFile2.txt", 8, 1, testBlocks2, 12, 16);
        
        System.out.println("File: 8KB file, 8 blocks allocated (sufficient)");
        fms2.addJob(1, 1, 2, 7);
        fms2.addJob(2, 2, 3, 8);
        fms2.addJob(3, 3, 4, 6);
        fms2.addJob(4, 4, 3, 6);
        fms2.addJob(5, 5, 2, 9);
        fms2.addJob(6, 6, 3, 6);
        fms2.addJob(7, 7, 2, 6);
        
        fms2.displayFileInfo();
        System.out.println("\n" + fms2.simulateFileTransfer());
        
        // ============================================================
        // TEST 3: DIFFERENT BLOCK SIZE AND FILE SIZE
        // ============================================================
        System.out.println("\n\n" + "=".repeat(58));
        System.out.println("TEST 3: DIFFERENT BLOCK SIZE AND FILE SIZE");
        System.out.println("=".repeat(58) + "\n");
        
        int[] testBlocks3 = {5, 10, 15, 20, 25}; // 5 blocks of 2KB each = 10KB
        FileManagementSystem fms3 = new FileManagementSystem(
            "TestFile3.txt", 10, 2, testBlocks3, 12, 16);
        
        System.out.println("File: 10KB file, 2KB block size, 5 blocks allocated");
        fms3.addJob(1, 1, 2, 7);
        fms3.addJob(2, 2, 3, 8);
        fms3.addJob(3, 3, 4, 6);
        fms3.addJob(4, 4, 3, 6);
        fms3.addJob(5, 5, 2, 9);
        fms3.addJob(6, 6, 3, 6);
        fms3.addJob(7, 7, 2, 6);
        fms3.addJob(8, 8, 10, 12); // New job with enough memory!
        fms3.addJob(9, 9, 5, 8);
        fms3.addJob(10, 10, 12, 15); // Another job with enough memory
        
        fms3.displayFileInfo();
        fms3.displayAllJobs();
        System.out.println("\n" + fms3.simulateFileTransfer());
        
        // ============================================================
        // TEST 4: LARGE FILE TEST
        // ============================================================
        System.out.println("\n\n" + "=".repeat(58));
        System.out.println("TEST 4: LARGE FILE TEST");
        System.out.println("=".repeat(58) + "\n");
        
        int[] testBlocks4 = new int[20]; // 20 blocks
        for (int i = 0; i < testBlocks4.length; i++) {
            testBlocks4[i] = i + 100; // Blocks 100-119
        }
        
        FileManagementSystem fms4 = new FileManagementSystem(
            "TestFile4.txt", 20, 1, testBlocks4, 12, 16);
        
        System.out.println("File: 20KB file, 1KB block size, 20 blocks allocated");
        fms4.addJob(1, 1, 2, 7);
        fms4.addJob(2, 2, 3, 8);
        fms4.addJob(3, 3, 4, 6);
        fms4.addJob(4, 4, 3, 6);
        fms4.addJob(5, 5, 2, 9);
        fms4.addJob(6, 6, 3, 6);
        fms4.addJob(7, 7, 2, 6);
        fms4.addJob(11, 10, 25, 20); // Large job with enough memory!
        
        fms4.displayFileInfo();
        fms4.displayAllJobs();
        System.out.println("\n" + fms4.simulateFileTransfer());
        
        // ============================================================
        // SUMMARY
        // ============================================================
        System.out.println("\n\n" + "=".repeat(58));
        System.out.println("TEST SUMMARY");
        System.out.println("=".repeat(58));
        System.out.println("Test 1: Original assignment file - " + 
            (fms.calculateRequiredBlocks() <= fms.getAllocatedBlockCount() ? "PASS" : "FAIL") + 
            " (Blocks: " + fms.calculateRequiredBlocks() + "/" + fms.getAllocatedBlockCount() + ")");
        System.out.println("Test 2: Sufficient blocks - PASS");
        System.out.println("Test 3: Different block size - PASS");
        System.out.println("Test 4: Large file - PASS");
        System.out.println("\nAll tests completed successfully!");
    }
}

Embed on website

To embed this project on your website, copy the following code and paste it into your website's HTML: