File Handling refers to the process of reading from and writing to files to store and retrieve data persistently on disk. It is vital in object-oriented software for application logging, configuration management, and user data persistence.
Before attempting I/O operations, modern object-oriented code inspects paths and verifies file properties.
import java.io.File;
public class Main {
public static void main(String[] args) {
File file = new File("example.txt");
if (file.exists()) {
System.out.println("File Name: " + file.getName());
System.out.println("Absolute Path: " + file.getAbsolutePath());
System.out.println("Writable: " + file.canWrite());
System.out.println("Readable: " + file.canRead());
System.out.println("File Size in bytes: " + file.length());
} else {
System.out.println("The file does not exist.");
}
}
}
#include <iostream>
#include <filesystem>
using namespace std;
namespace fs = std::filesystem;
int main() {
fs::path p("example.txt");
if (fs::exists(p)) {
cout << "File Name: " << p.filename().string() << "\n";
cout << "Absolute Path: " << fs::absolute(p).string() << "\n";
cout << "File Size in bytes: " << fs::file_size(p) << "\n";
} else {
cout << "The file does not exist.\n";
}
return 0;
}
from pathlib import Path
def main():
p = Path("example.txt")
if p.exists():
print("File Name:", p.name)
print("Absolute Path:", str(p.resolve()))
print("File Size in bytes:", p.stat().st_size)
else:
print("The file does not exist.")
if __name__ == "__main__":
main()
Writing data converts application strings into character streams on disk. Buffering is used to group small write requests for better disk performance.
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
public class Main {
public static void main(String[] args) {
try (BufferedWriter writer = new BufferedWriter(new FileWriter("output.txt"))) {
writer.write("Hello, world!\n");
writer.write("This is a sample file.");
System.out.println("File written successfully.");
} catch (IOException e) {
e.printStackTrace();
}
}
}
#include <iostream>
#include <fstream>
using namespace std;
int main() {
ofstream writer("output.txt");
if (!writer.is_open()) {
cout << "Failed to open output.txt\n";
return 0;
}
writer << "Hello, world!\n";
writer << "This is a sample file.\n";
writer.close();
cout << "File written successfully.\n";
return 0;
}
def main():
try:
with open("output.txt", "w") as writer:
writer.write("Hello, world!\n")
writer.write("This is a sample file.\n")
print("File written successfully.")
except Exception:
print("Failed to write the file.")
if __name__ == "__main__":
main()
Iterating line-by-line is memory efficient, allowing applications to process files much larger than available RAM.
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class Main {
public static void main(String[] args) {
try (BufferedReader reader = new BufferedReader(new FileReader("example.txt"))) {
String line;
int i = 1;
while ((line = reader.readLine()) != null) {
System.out.println("Line " + i + ": " + line);
i++;
}
} catch (IOException e) {
System.out.println("Error reading file.");
}
}
}
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main() {
ifstream reader("example.txt");
if (!reader.is_open()) {
cout << "Failed to open example.txt\n";
return 0;
}
string line;
int i = 1;
while (getline(reader, line)) {
cout << "Line " << i << ": " << line << "\n";
i++;
}
reader.close();
return 0;
}
def main():
try:
with open("example.txt", "r") as reader:
i = 1
for line in reader:
print(f"Line {i}: {line.strip()}")
i += 1
except FileNotFoundError:
print("The file does not exist.")
if __name__ == "__main__":
main()
File handles are limited system resources. Forgetting to close streams causes file locks and memory leaks.
try (BufferedReader reader = ...) automatically calls close() upon
block exit.
std::ifstream and
std::ofstream destructors run automatically when the object leaves scope,
closing the file handle.
with open(...) as f: ensures the
stream is closed automatically even if exceptions occur.
Logging uses append mode so new messages are added to the audit file without wiping prior entries.
import java.io.*;
class Logger {
private String path;
public Logger(String path) throws IOException {
this.path = path;
File file = new File(path);
if (!file.exists()) {
file.createNewFile();
}
}
public void log(String message) {
// FileWriter with true parameter enables append mode
try (BufferedWriter bw = new BufferedWriter(new FileWriter(path, true))) {
bw.write(message);
bw.newLine();
} catch (Exception e) {
System.out.println("Failed to log: " + message);
}
}
}
public class Main {
public static void main(String[] args) throws Exception {
Logger logger = new Logger("application.log");
logger.log("Application started...");
logger.log("User logged in.");
logger.log("Application closed.");
}
}
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
class Logger {
private:
string path;
public:
Logger(const string& path) : path(path) {
ofstream tmp(path, ios::app);
tmp.close();
}
void log(const string& message) {
// ios::app enables append mode
ofstream out(path, ios::app);
if (!out.is_open()) return;
out << message << "\n";
out.close();
}
};
int main() {
Logger logger("application.log");
logger.log("Application started...");
logger.log("User logged in.");
logger.log("Application closed.");
return 0;
}
class Logger:
def __init__(self, path):
self.path = path
# Ensure file exists
with open(self.path, "a"):
pass
def log(self, message):
try:
# Mode 'a' enables append mode
with open(self.path, "a") as writer:
writer.write(message + "\n")
except Exception:
print("Failed to log:", message)
def main():
logger = Logger("application.log")
logger.log("Application started...")
logger.log("User logged in.")
logger.log("Application closed...")
if __name__ == "__main__":
main()
| Feature | Java | C++ | Python |
|---|---|---|---|
| File Metadata API | java.io.File |
std::filesystem::path (C++17) |
pathlib.Path / os module |
| Buffered Write API | BufferedWriter(new FileWriter(path)) |
std::ofstream writer(path) |
open(path, "w") (built-in buffering) |
| Line Reader API | BufferedReader(new FileReader(path)) |
std::ifstream with getline() |
Line iteration over open(path, "r") |
| Auto Resource Closing | try-with-resources |
RAII (destructors auto-close on scope exit) | with statement (Context Manager) |
| Append Mode | new FileWriter(path, true) |
ofstream(path, ios::app) |
open(path, "a") |
What is the main purpose of Java's try-with-resources statement in File
Handling?
Which mode should be used when opening a file to add logs without overwriting existing data?
Definition ⇒ Reading/writing files for persistent data storage on disk
Modes ⇒ Read (r / ifstream) ; Write (w /
ofstream) ; Append (a / ios::app)
Java ⇒ try-with-resources auto-closes AutoCloseable streams
C++ ⇒ RAII destructors auto-close ifstream / ofstream handles on
scope exit
Python ⇒ with open(...) context manager auto-closes files on exit
Java ⇒ File class (exists(), length(),
getAbsolutePath())
C++ ⇒ C++17 std::filesystem (exists(), file_size(),
absolute())
Python ⇒ pathlib.Path (exists(), stat().st_size,
resolve())
Primary source: Oracle Java Tutorials — Basic I/O, cppreference — fstream & Python Docs — Reading and Writing Files. Ask me anything that's unclear.
Questions? Ask your agent — you can follow up on any concept, quiz answer, or how this applies to a specific coding problem. Review the Java glossary or syntax quick reference for a compressed overview.