What is IO?
IO stands for Input and Output, referring to input streams and output streams. Input streams read data from a source, while output streams write data to a destination.
The following diagram illustrates how IO streams work:
File Operations with IO Streams
IO streams for file operations are divided into two main categoreis: character streams and byte streams.
Character Streams
Character streams are built around two abstract classes: Writer and Reader. Their concrete implementations, FileWriter and FileReader, handle file read and write operations. BufferedWriter and BufferedReader provide buffering functionality to improve perforamnce.
When learning Java, character streams are commonly used for reading and writing characters through the console. For example, a program that reads user input and processes it until the user types "quit".
Code Example:
public static void main(String[] args) {
try {
readConsoleInput();
} catch (IOException e) {
e.printStackTrace();
}
}
private static void readConsoleInput() throws IOException {
String input;
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
System.out.println("Enter text, type 'quit' to exit.");
do {
input = reader.readLine();
System.out.println("You entered: " + input);
} while (!input.equals("quit"));
reader.close();
}
When running this code and entering hello and quit:
Enter text, type 'quit' to exit.
hello
You entered: hello
You entered:
quit
You entered: quit
Character streams are primarily used for reading and writing text files, such as those with .txt extensions.
Code Example:
private static void fileReadWrite() throws IOException {
String filePath = "E:/data/sample.txt";
String content = "hello world";
FileWriter writer = new FileWriter(filePath);
writer.write(content);
writer.close();
FileReader reader = new FileReader(filePath);
StringBuilder builder = new StringBuilder();
while (reader.ready()) {
builder.append((char) reader.read());
}
System.out.println("Content: " + builder.toString());
reader.close();
}
Note: Use File.separator for cross-platform compatibility with file paths.
Output:
Content: hello world
The FileWriter and FileReader classes directly access the disk, which is inefficient. For file operations, buffered streams are preferred. Buffered I/O works like collecting garbage—you gather it up first and then dispose of it all at once instead of扔一点垃圾就跑一次.
Code Example:
private static void bufferedFileOperations() throws IOException {
String filePath = "E:/data/sample.txt";
String content = "Hello!";
FileWriter fileWriter = new FileWriter(filePath);
BufferedWriter bufferedWriter = new BufferedWriter(fileWriter);
bufferedWriter.write(content);
bufferedWriter.close();
fileWriter.close();
FileReader fileReader = new FileReader(filePath);
BufferedReader bufferedReader = new BufferedReader(fileReader);
StringBuilder builder = new StringBuilder();
while (bufferedReader.ready()) {
builder.append((char) bufferedReader.read());
}
System.out.println("Content: " + builder.toString());
bufferedReader.close();
fileReader.close();
}
Note: Always close the buffered stream first, then close the underlying stream.
Byte Streams
Byte streams are built around two abstract classes: InputStream and OutputStream. Their implementations, FileInputStream and FileOutputStream, handle file read and write operations. BufferedInputStream and BufferedOutputStream provide buffering functionality.
Byte streams can read text but are primarily used for binary files like music, video, and image files where direct text extraction isn't possible.
Code Example:
private static void copyWithNewFile() throws IOException {
String sourcePath = "E:/data/sample.txt";
String targetPath = "E:/data/Greeting.txt";
String additionalText = "Hello!";
InputStream inputStream = new FileInputStream(sourcePath);
InputStreamReader streamReader = new InputStreamReader(inputStream, StandardCharsets.UTF_8);
StringBuilder content = new StringBuilder();
while (streamReader.ready()) {
content.append((char) streamReader.read());
}
inputStream.close();
streamReader.close();
OutputStream outputStream = new FileOutputStream(targetPath);
OutputStreamWriter streamWriter = new OutputStreamWriter(outputStream, StandardCharsets.UTF_8);
streamWriter.write(content + additionalText);
streamWriter.close();
outputStream.close();
InputStream input2 = new FileInputStream(targetPath);
InputStreamReader reader2 = new InputStreamReader(input2, StandardCharsets.UTF_8);
StringBuilder result = new StringBuilder();
while (reader2.ready()) {
result.append((char) reader2.read());
}
System.out.println("Content: " + result);
input2.close();
reader2.close();
}
Output:
Content: hello worldHello!
The result shows the original content combined with the new text, as expected.
The File Class
The File class handles directory and file system operations such as creating, deleting, and inspecting directories and files.
Code Example:
private static void fileOperations() throws IOException {
String dirPath = "E:/projects/demo";
String nestedPath = "E:/projects/nested/deep";
String filePath = "E:/projects/demo/sample.txt";
File directory = new File(dirPath);
File deepDirectory = new File(nestedPath);
File targetFile = new File(filePath);
System.out.println("mkdir result: " + directory.mkdir());
System.out.println("mkdirs result: " + deepDirectory.mkdirs());
System.out.println("createNewFile result: " + targetFile.createNewFile());
System.out.println("getName: " + targetFile.getName());
System.out.println("getParent: " + targetFile.getParent());
System.out.println("getPath: " + targetFile.getPath());
System.out.println("isDirectory: " + deepDirectory.isDirectory());
System.out.println("isDirectory (file): " + targetFile.isDirectory());
System.out.println("delete result: " + targetFile.delete());
}
Output:
mkdir result: true
mkdirs result: true
createNewFile result: true
getName: sample.txt
getParent: E:\projects\demo
getPath: E:\projects\demo\sample.txt
isDirectory: true
isDirectory (file): false
delete result: true
When performing file creation and deletion operations, always verify the file or directory exists beforehand to avoid exceptions.