Advanced Java ProgrammingUnit 914 min read
Java Mail API & File Handling: Sending Emails & Processing Files
Unit 9 of Advanced Java Programming covers Java’s built-in email API for sending/receiving emails programmatically, and advanced file I/O (reading, writing, searching, and parsing files) with practical examples like log analysis, data extraction, and email automation. Learn to handle attachments, MIME types, and file f
TAKEAWAYS:
- Java Mail API lets you send/receive emails programmatically using SMTP/IMAP protocols, with support for HTML emails, attachments, and authentication.
- File Handling in Java includes reading/writing text/binary files, searching patterns (regex), and parsing structured data (CSV, JSON) using
BufferedReader,FileWriter, andScanner. - Email Structure: MIME types (e.g.,
text/plain,multipart/mixed) define how email content (text, HTML, attachments) is encoded and transmitted. - File Operations: Methods like
Files.readAllLines(),Files.write(), andPath(NIO.2) simplify file handling compared to legacyFile/FileInputStream. - Error Handling: Always wrap file/email operations in
try-catchblocks to handleIOException,MessagingException, orAuthenticationFailedException. - Real-World Use: Automate email notifications (e.g., order confirmations in Daraz), parse log files (e.g., NTC server logs), or generate reports from CSV data (e.g., NEPSE stock analysis).
1. Java Mail API: Sending Emails Programmatically
The JavaMail API (part of the javax.mail package) enables Java programs to send, receive, and parse emails using standard protocols like SMTP (sending) and IMAP/POP3 (receiving). It abstracts low-level email protocols into high-level objects like Session, Message, and Transport.
Key Components
classDiagram
class Session {
+Properties getProperties()
+Transport getTransport()
}
class Message {
+void setFrom(Address)
+void setRecipients(Message.RecipientType, Address[])
+void setSubject(String)
+void setContent(Object, String)
}
class Transport {
+void send(Message)
+void close()
}
Session --> Message : creates
Message --> Transport : uses to sendHow It Works
- Configure a
Sessionwith SMTP server details (host, port, credentials). - Create a
Messageobject, setting sender, recipients, subject, and content (text/HTML). - Attach files (if needed) using
MimeBodyPartandMultipart. - Send via
Transport.send().
Example: Sending an Email with Attachment
import javax.mail.*;
import javax.mail.internet.*;
import java.util.Properties;
public class EmailSender {
public static void main(String[] args) {
// 1. Set SMTP properties (e.g., Gmail)
Properties props = new Properties();
props.put("mail.smtp.host", "smtp.gmail.com");
props.put("mail.smtp.port", "587");
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.starttls.enable", "true");
// 2. Create session with credentials
Session session = Session.getInstance(props, new Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication("your_email@gmail.com", "your_password");
}
});
try {
// 3. Create message
Message message = new MimeMessage(session);
message.setFrom(new InternetAddress("your_email@gmail.com"));
message.setRecipients(Message.RecipientType.TO, InternetAddress.parse("recipient@example.com"));
message.setSubject("Test Email with Attachment");
// 4. Add text and HTML parts
MimeBodyPart textPart = new MimeBodyPart();
textPart.setText("Hello, this is a test email.");
MimeBodyPart htmlPart = new MimeBodyPart();
htmlPart.setContent("<h1>HTML Content</h1><p>This is <b>bold</b>.</p>", "text/html");
Multipart multipart = new MimeMultipart();
multipart.addBodyPart(textPart);
multipart.addBodyPart(htmlPart);
// 5. Attach a file
MimeBodyPart attachmentPart = new MimeBodyPart();
attachmentPart.attachFile(new File("example.pdf"));
multipart.addBodyPart(attachmentPart);
message.setContent(multipart);
// 6. Send
Transport.send(message);
System.out.println("Email sent successfully!");
} catch (MessagingException e) {
e.printStackTrace();
}
}
}
Visual: Email MIME Structure
Common Exceptions
| Exception | Cause | Solution |
|---|---|---|
AuthenticationFailedException |
Wrong username/password or 2FA blocked | Use an app-specific password (Gmail). |
SocketException |
SMTP server unreachable | Check firewall/VPN or server status. |
MessagingException |
Invalid email format | Validate recipients with InternetAddress.validate(). |
2. File Handling in Java: Reading, Writing, and Parsing
Java provides multiple ways to handle files:
- Legacy I/O:
File,FileReader,FileWriter(simpler but less flexible). - NIO.2 (New I/O):
Path,Files,BufferedReader(recommended for modern code).
Key Classes
classDiagram
class Path {
+InputStream newInputStream()
+OutputStream newOutputStream()
+List~String~ readAllLines()
}
class Files {
+static Path of(String)
+static void write(Path, CharSequence, Charset)
+static void copy(Path, Path, CopyOption...)
}
class BufferedReader {
+String readLine()
+void close()
}
Path --> Files : static methods
Path --> BufferedReader : createsExample 1: Copying Words Starting with Vowels (Exam Question)
Task: Copy words starting with vowels from ONE.TXT to TWO.TXT.
import java.nio.file.*;
import java.util.regex.*;
public class VowelWordCopier {
public static void main(String[] args) throws Exception {
Path input = Paths.get("ONE.TXT");
Path output = Paths.get("TWO.TXT");
// Read all lines and filter words starting with vowels
String content = Files.readString(input);
Pattern vowelPattern = Pattern.compile("\\b[AEIOUaeiou]\\w*\\b");
Matcher matcher = vowelPattern.matcher(content);
// Write matches to output file
Files.write(output, matcher.results().map(MatchResult::group).toList());
}
}
Visual: File Processing Steps
1. Open input file (ONE.TXT) → 2. Read content → 3. Apply regex filter → 4. Write matches to output file (TWO.TXT).
Example 2: Parsing a CSV File (Real-World Use)
Scenario: NEPSE stock data is stored in stocks.csv with columns: Symbol,Price,Change.
import java.nio.file.*;
import java.util.*;
public class StockParser {
public static void main(String[] args) throws Exception {
Path csvFile = Paths.get("stocks.csv");
List<String> lines = Files.readAllLines(csvFile);
// Skip header and parse each line
for (int i = 1; i < lines.size(); i++) {
String[] data = lines.get(i).split(",");
String symbol = data[0];
double price = Double.parseDouble(data[1]);
double change = Double.parseDouble(data[2]);
System.out.printf("%s: %.2f (Change: %.2f%%)\n", symbol, price, change);
}
}
}
Visual: CSV Parsing Example
Common File Operations
| Operation | Legacy I/O | NIO.2 (Recommended) |
|---|---|---|
| Read entire file | Files.readAllBytes() |
Files.readString() |
| Write to file | FileWriter |
Files.write() |
| Line-by-line reading | BufferedReader |
Files.lines() → Stream |
| Directory listing | File.listFiles() |
Files.list() |
| File locking | Not supported | FileLock (NIO.2) |
## In the Real World
eSewa/Khalti Payment Notifications
- Idea Used: Java Mail API sends automated email receipts to users after transactions.
- How: After a payment, the system constructs a
Messagewith transaction details (amount, timestamp) and sends it via SMTP. Attachments (e.g., PDF receipts) useMimeBodyPart.
Daraz Order Processing
- Idea Used: File handling parses order logs (CSV/JSON) to generate reports.
- How: A
BufferedReaderreadsorders_2023.csv, filters completed orders, and writes summaries tosales_report.txtusingFiles.write().
NTC Network Log Analysis
- Idea Used: Regex in file handling extracts error patterns from log files.
- How:
Pattern.compile("ERROR: \\d+")scansntc_logs.txtto count network failures, written toerror_summary.log.
Bank Loan Interest Calculations (Global Bank)
- Idea Used: File I/O reads customer data (CSV) and calculates interest using
Scanner. - Worked Example:
- Input (
customers.csv):ID,Principal,Rate,Time 1,10000,5,2 2,20000,6,1 - Code:
double interest = (principal * rate * time) / 100; Files.write(Path.of("interest.txt"), String.valueOf(interest).getBytes()); - Output:
interest.txtcontains1000(for customer 1).
- Input (
- Idea Used: File I/O reads customer data (CSV) and calculates interest using
3. Advanced Topics
A. Handling Large Files with Streams
For files >10MB, use streams to avoid memory overload:
try (Stream<String> lines = Files.lines(Path.of("large_log.txt"))) {
lines.filter(line -> line.contains("ERROR"))
.forEach(System.out::println);
}
B. Serialization (Saving Objects to Files)
Convert Java objects to/from files using ObjectOutputStream:
// Save
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("data.ser"));
oos.writeObject(customerList);
// Load
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("data.ser"));
List<Customer> loadedList = (List<Customer>) ois.readObject();
C. File Locking (Avoiding Concurrent Access)
try (FileLock lock = Files.lock(Path.of("config.txt"), LockOption.NONE)) {
// Critical section: modify file
} catch (OverlappingFileLockException e) {
System.err.println("File is locked by another process!");
}
## Exam Tip
For Java Mail API Questions:
- Always include SMTP properties (host, port, auth) and exception handling (
MessagingException). - Use
MimeMultipartfor emails with attachments or mixed content. - Common Pitfalls:
- Forgetting
Transport.send(). - Not enabling TLS (
mail.smtp.starttls.enable). - Hardcoding passwords (use environment variables in production).
- Forgetting
- Always include SMTP properties (host, port, auth) and exception handling (
For File Handling Questions:
- Path vs. File: Prefer
Path(NIO.2) for modern code. Example:Path path = Paths.get("data.txt"); // Better than File file = new File("data.txt"); - Regex Tricks: Use
\\bfor word boundaries (e.g.,\b[AEIOU]\\w*). - File Formats:
- CSV: Split by
,and skip headers. - Binary: Use
Files.readAllBytes()andDataInputStream.
- CSV: Split by
- Exam Shortcuts:
- To read a file line-by-line:
Files.lines(path).forEach(System.out::println). - To write:
Files.write(path, "content".getBytes()).
- To read a file line-by-line:
- Path vs. File: Prefer
Past Exam Patterns:
- Programming Questions: Expect tasks like:
- Filter words from a file (regex).
- Parse CSV/JSON data.
- Send an email with attachments.
- Theory Questions: Focus on:
- JavaMail architecture (Session → Message → Transport).
- NIO.2 vs. legacy I/O (advantages of
Path/Files). - MIME types (
text/plain,multipart/mixed).
- Programming Questions: Expect tasks like:
Code Templates:
- Email Sender:
Session session = Session.getInstance(props, authenticator); Message message = new MimeMessage(session); // ... set properties ... Transport.send(message); - File Reader:
try (Stream<String> lines = Files.lines(path)) { lines.filter(...).forEach(...); }
- Email Sender:
Visual Summary:
| Feature | Java Mail API | File Handling (NIO.2) |
|-----------------------|----------------------------------------|-------------------------------------|
| Purpose | Send/receive emails | Read/write files |
| Key Classes | Session, Message, Transport | Path, Files, BufferedReader |
| Protocols | SMTP, IMAP, POP3 | N/A |
| Common Exceptions | MessagingException | IOException, FileNotFoundException |
| Modern Alternative | N/A | NIO.2 (Path, Files) |
In the real world
- Daraz Order Confirmations: Uses JavaMail API to send automated email notifications with order details (HTML + attachments like invoices) to customers after purchase. The
MimeMultipartstructure ensures compatibility across email clients. - NTC Server Log Analysis: Java’s
Files.readAllLines()and regex parsing (Pattern/Matcher) extract error patterns from log files (e.g.,SocketExceptionentries) to generate daily reports for network administrators. - NEPSE Stock Data Processing: CSV files from NEPSE are parsed using
ScannerorFiles.lines()to calculate daily price changes, which are then emailed to subscribers via JavaMail’sTransport.send().
Based on the TU BSc CSIT syllabus for Advanced Java Programming (CSC409), unit 9.
Discussion
Loading…