National University of Technology
Computer Science Department
Program : Software Engineering
Course : SCDA
Lab 06
Submitted To: Submitted By:
Lec. Momina Mir Taha Mehmood
F23608003
Task 1:
File Handling with Multiple Exceptions
Create a Java program that reads a file specified by the user. Handle the following exceptions:
1. FileNotFoundException - if the file does not exist
2. IOException - for other file reading errors
3. SecurityException - if the program doesn't have permission to read the file
Use a finally block to ensure that the file is closed properly, even if an exception occurs. Add a
message in the finally block indicating whether the file was closed successfully or if there was
an issue closing it.
Code :
package lab6_scd;
import java.io.*;
import java.util.Scanner;
public class FileReaderWithExceptions {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.print("Enter the file path: ");
String filePath = scanner.nextLine();
scanner.close();
FileReader fileReader = null;
BufferedReader bufferedReader = null;
try {
fileReader = new FileReader(filePath);
bufferedReader = new BufferedReader(fileReader);
String line;
System.out.println("File content:");
while ((line = bufferedReader.readLine()) != null) {
System.out.println(line);
}
} catch (FileNotFoundException e) {
System.out.println("Error: The file was not found.");
} catch (IOException e) {
System.out.println("Error: An I/O error occurred while reading the file.");
} catch (SecurityException e) {
System.out.println("Error: Permission denied to read the file.");
} finally {
try {
if (bufferedReader != null) {
bufferedReader.close();
System.out.println("BufferedReader closed successfully.");
}
if (fileReader != null) {
fileReader.close();
System.out.println("FileReader closed successfully.");
}
} catch (IOException e) {
System.out.println("Error: Failed to close the file properly.");
}
}
}
}
Output:
Task 2:
Arithmetic Operations with Custom Exception
Create a Java program that performs division of two numbers entered by the user. Implement
the following:
1. Handle ArithmeticException for division by zero
2. Create a custom exception InvalidInputException for negative numbers
3. Use a finally block to display a message indicating the completion of the operation
Code :
package lab6_scd;
import java.util.Scanner;
// Custom exception for invalid input (negative numbers)
class InvalidInputException extends Exception {
public InvalidInputException(String message) {
super(message);
}
}
public class task2 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
try {
System.out.print("Enter numerator: ");
int numerator = scanner.nextInt();
System.out.print("Enter denominator: ");
int denominator = scanner.nextInt();
// Check for negative numbers
if (numerator < 0 || denominator < 0) {
throw new InvalidInputException("Negative numbers are not allowed.");
}
// Perform division
int result = numerator / denominator;
System.out.println("Result: " + result);
} catch (ArithmeticException e) {
System.out.println("Error: Division by zero is not allowed.");
} catch (InvalidInputException e) {
System.out.println("Error: " + e.getMessage());
} finally {
System.out.println("Operation completed.");
scanner.close();
}
}
}
Output:
Task 3:
Bank Account Operations
Create a Java program that simulates bank account operations. Implement the following:
1. Handle IllegalArgumentException for invalid account numbers
2. Handle InsufficientFundsException (custom exception) for withdrawal amounts
exceeding balance
3. Use nested try-catch blocks for different operations (deposit, withdrawal, balance
check)
4. Implement a finally block that logs the transaction details to a file
Code :
package lab6_scd;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Scanner;
// Custom exception for insufficient funds
class InsufficientFundsException extends Exception {
public InsufficientFundsException(String message) {
super(message);
}
}
class BankAccount {
private String accountNumber;
private double balance;
public BankAccount(String accountNumber, double initialBalance) {
if (!accountNumber.matches("taha1234")) {
throw new IllegalArgumentException("Invalid account number. It should be 6-12 digits long.");
}
this.accountNumber = accountNumber;
this.balance = initialBalance;
}
public void deposit(double amount) {
if (amount <= 0) {
throw new IllegalArgumentException("Deposit amount must be positive.");
}
balance += amount;
System.out.println("Deposited: " + amount);
}
public void withdraw(double amount) throws InsufficientFundsException {
if (amount > balance) {
throw new InsufficientFundsException("Insufficient balance for withdrawal.");
}
balance -= amount;
System.out.println("Withdrawn: " + amount);
}
public void checkBalance() {
System.out.println("Current balance: " + balance);
}
public String getTransactionDetails() {
return "Account: " + accountNumber + ", Balance: " + balance;
}
}
public class task3 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
BankAccount account = null;
try {
System.out.print("Enter account number: ");
String accountNumber = scanner.next();
account = new BankAccount(accountNumber, 1000.0); // Initial balance
System.out.print("Enter amount to deposit: ");
double depositAmount = scanner.nextDouble();
account.deposit(depositAmount);
try {
System.out.print("Enter amount to withdraw: ");
double withdrawAmount = scanner.nextDouble();
account.withdraw(withdrawAmount);
} catch (InsufficientFundsException e) {
System.out.println("Error: " + e.getMessage());
}
account.checkBalance();
} catch (IllegalArgumentException e) {
System.out.println("Error: " + e.getMessage());
} finally {
try (FileWriter writer = new FileWriter("transactions.log", true)) {
if (account != null) {
writer.write(account.getTransactionDetails() + "\n");
System.out.println("Transaction logged successfully.");
}
} catch (IOException e) {
System.out.println("Error logging transaction: " + e.getMessage());
}
scanner.close();
}
}
}
Output:
Task 4:
Network Connection Simulation
Create a Java program that simulates connecting to a network resource. Implement the
following:
1. Handle UnknownHostException for invalid host names
2. Handle SocketTimeoutException for connection timeouts
3. Use a finally block to close the connection properly, even if an exception occurs
4. Implement a custom exception ConnectionFailedException for other connection-related
Issues
Code :
package lab6_scd;
import java.io.*;
import java.net.*;
import java.util.Scanner;
// Custom exception for connection failure
class ConnectionFailedException extends Exception {
public ConnectionFailedException(String message) {
super(message);
}
}
public class NetworkConnectionSimulation {
public static void main(String[] args) throws ConnectionFailedException {
Scanner scanner = new Scanner(System.in);
Socket socket = null;
try {
System.out.print("Enter the host name (e.g., www.example.com): ");
String hostName = scanner.nextLine();
System.out.print("Enter the port number: ");
int port = scanner.nextInt();
// Simulate connecting to the network resource
socket = new Socket();
socket.connect(new InetSocketAddress(hostName, port), 5000); // Timeout set to
5000ms
System.out.println("Successfully connected to the host: " + hostName);
} catch (UnknownHostException e) {
System.out.println("Error: Unknown host. The provided host name is invalid or
unreachable.");
} catch (SocketTimeoutException e) {
System.out.println("Error: Connection timed out. Unable to connect within the
specified time.");
} catch (IOException e) {
System.out.println("Error: An IO error occurred while trying to connect to the
network.");
} finally {
// Ensure the socket connection is properly closed
try {
if (socket != null && !socket.isClosed()) {
socket.close();
System.out.println("Connection closed.");
}
} catch (IOException e) {
System.out.println("Error while closing the connection: " + e.getMessage());
}
// Close the scanner to prevent resource leak
scanner.close();
}
}
}
Output:
Task 5:
Complex Nested Try-Catch Structure
Create a Java program that demonstrates a complex nested try-catch structure with multiple
finally blocks. The program should:
1. Have at least three levels of nested try-catch blocks
2. Handle different types of exceptions at different levels
3. Include finally blocks at each level that perform different cleanup operations
4. Demonstrate how exceptions propagate through different levels
5. Show how finally blocks execute even when exceptions are thrown
Code :
package lab6_scd;
import java.io.*;
public class ComplexNestedTryCatch {
public static void main(String[] args) {
// Simulate different levels of exception handling and finally blocks
try {
System.out.println("Outer try block (Level 1)");
try {
System.out.println(" Inner try block (Level 2)");
try {
System.out.println(" Innermost try block (Level 3)");
// Simulate an arithmetic exception
int result = 10 / 0; // This will throw ArithmeticException
} catch (ArithmeticException e) {
System.out.println(" Caught ArithmeticException in Level 3: " + e.getMessage());
throw new NullPointerException("Simulating a NullPointerException after catching
ArithmeticException");
} finally {
System.out.println(" Finally block of Level 3: Performing cleanup tasks.");
}
} catch (NullPointerException e) {
System.out.println(" Caught NullPointerException in Level 2: " + e.getMessage());
throw new IOException("Simulating IOException after catching NullPointerException");
} finally {
System.out.println(" Finally block of Level 2: Performing other cleanup tasks.");
}
} catch (IOException e) {
System.out.println("Caught IOException in Level 1: " + e.getMessage());
} finally {
System.out.println("Finally block of Level 1: Final cleanup tasks.");
}
}
}
Output: