Most programs need to collect input information and output results, and the forms of input and output are diverse. Let’s start with the most basic standard input and output.
Introduction to Input and Output
In Java programs, the most basic input and output occur in the console (command-line interface). We implement them through the following two core classes:
- Output: System.out (console output)
- Input: Scanner (console input)
Basic Output
public static void main(String[] args) {
// Most basic output
System.out.println("Hello, Java World!");
// Formatted output
String name = "Xiao Ming";
int age = 20;
System.out.printf("Name: %s, Age: %d%n", name, age);
// Output without line break
System.out.print("First segment");
System.out.print("Second segment");
}
Comparison of output methods:
Method | Description | Example |
---|---|---|
System.out.print() | Output content without line break | print(“Hello”) |
System.out.println() | Output content with automatic line break | println(“World”) |
System.out.printf() | Formatted output (similar to C language) | printf(“PI: %.2f”, 3.14) |
Basic Input
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.print("Please enter your name: ");
String name = scanner.nextLine();
System.out.print("Please enter your age: ");
int age = scanner.nextInt();
System.out.printf("%s, you are %d years old!%n", name, age);
scanner.close(); // Remember to close!
}
Common input methods:
Method | Description | Example Input → Return Value |
---|---|---|
next() | Reads a single word (space-separated) | “Hello World” → “Hello” |
nextLine() | Reads an entire line of text | “Java Programming” → “Java Programming” |
nextInt() | Reads an integer | “25” → 25 |
nextDouble() | Reads a floating-point number | “3.14” → 3.14 |
Printing output to the “standard output stream” (i.e., the console window) is very simple, just call System.out.println. Reading from the “standard input stream” System.in is not that straightforward. To read console input, you first need to construct a Scanner object associated with the “standard input stream” System.in.
Other I/O Methods
Java’s I/O system supports multiple scenarios through different streams and utility classes, including file operations, network communication, memory operations, and compression. Choosing the appropriate stream type (byte stream vs. character stream) and utility classes (such as Files or NIO) according to requirements can significantly improve development efficiency.
1. File Reading and Writing
// Byte stream file copying
try (FileInputStream fis = new FileInputStream("input.txt");
FileOutputStream fos = new FileOutputStream("output.txt")) {
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = fis.read(buffer)) != -1) {
fos.write(buffer, 0, bytesRead);
}
}
// Character stream for text processing
try (BufferedReader reader = new BufferedReader(new FileReader("input.txt"));
BufferedWriter writer = new BufferedWriter(new FileWriter("output.txt"))) {
String line;
while ((line = reader.readLine()) != null) {
writer.write(line.toUpperCase());
writer.newLine();
}
}
2. Memory Operation Streams
// Byte array stream
ByteArrayOutputStream baos = new ByteArrayOutputStream();
baos.write("Hello Memory".getBytes(StandardCharsets.UTF_8));
byte[] result = baos.toByteArray();
// Character array stream
CharArrayWriter caw = new CharArrayWriter();
caw.write("CharArrayWriter example");
char[] charResult = caw.toCharArray();
NIO New Features
1. Path and Files Utility Class
Path source = Paths.get("source.txt");
Path target = Paths.get("target.txt");
// File copying (NIO way)
Files.copy(source, target, StandardCopyOption.REPLACE_EXISTING);
// Traverse directory
try (Stream<Path> paths = Files.walk(Paths.get("/data"))) {
paths.filter(Files::isRegularFile)
.forEach(System.out::println);
}
2. Channel and Buffer
try (FileChannel channel = FileChannel.open(
Paths.get("data.bin"),
StandardOpenOption.READ)) {
ByteBuffer buffer = ByteBuffer.allocate(1024);
while (channel.read(buffer) > 0) {
buffer.flip(); // Switch to read mode
while (buffer.hasRemaining()) {
System.out.print((char) buffer.get());
}
buffer.clear(); // Clear the buffer
}
}
Advanced Data Operations
1. Data Streams for Primitive Types
try (DataOutputStream dos = new DataOutputStream(
new FileOutputStream("data.dat"))) {
dos.writeInt(2023);
dos.writeDouble(Math.PI);
dos.writeBoolean(true);
}
try (DataInputStream dis = new DataInputStream(
new FileInputStream("data.dat"))) {
System.out.println(dis.readInt()); // 2023
System.out.println(dis.readDouble()); // 3.141592653589793
System.out.println(dis.readBoolean()); // true
}
2. Object Serialization
class Student implements Serializable {
private static final long serialVersionUID = 1L;
private String name;
private transient int age; // Will not be serialized
// Constructor, getter/setter omitted
}
// Serialize object
try (ObjectOutputStream oos = new ObjectOutputStream(
new FileOutputStream("student.ser"))) {
oos.writeObject(new Student("Zhang San", 20));
}
// Deserialize
try (ObjectInputStream ois = new ObjectInputStream(
new FileInputStream("student.ser"))) {
Student s = (Student) ois.readObject();
System.out.println(s.getName()); // Outputs "Zhang San"
}
Network Communication
1. Basic Socket Communication
// Server
public class SimpleServer {
public static void main(String[] args) throws IOException {
try (ServerSocket server = new ServerSocket(8080);
Socket client = server.accept();
BufferedReader in = new BufferedReader(
new InputStreamReader(client.getInputStream()));
PrintWriter out = new PrintWriter(client.getOutputStream(), true)) {
String input = in.readLine();
out.println("Server response: " + input.toUpperCase());
}
}
}
// Client
public class SimpleClient {
public static void main(String[] args) throws IOException {
try (Socket socket = new Socket("localhost", 8080);
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
BufferedReader in = new BufferedReader(
new InputStreamReader(socket.getInputStream()))) {
out.println("Hello Server");
System.out.println("Response: " + in.readLine());
}
}
}
2. NIO Non-blocking Communication
Selector selector = Selector.open();
ServerSocketChannel serverChannel = ServerSocketChannel.open();
serverChannel.bind(new InetSocketAddress(8080));
serverChannel.configureBlocking(false);
serverChannel.register(selector, SelectionKey.OP_ACCEPT);
while (true) {
selector.select();
Set<SelectionKey> keys = selector.selectedKeys();
Iterator<SelectionKey> iter = keys.iterator();
while (iter.hasNext()) {
SelectionKey key = iter.next();
if (key.isAcceptable()) {
// Handle connection request
} else if (key.isReadable()) {
// Handle read event
}
iter.remove();
}
}
Recommended Third-party Libraries
1. Apache Commons IO
// Quick file operations
FileUtils.copyFile(new File("src.txt"), new File("dest.txt"));
// Read file content
List<String> lines = FileUtils.readLines(new File("data.log"), "UTF-8");
// Recursively delete directory
FileUtils.deleteDirectory(new File("/tmp/old_data"));
2. Google Guava
// File utility class
Files.asCharSource(new File("config.json"), Charsets.UTF_8)
.copyTo(Files.asCharSink(new File("config.bak"), Charsets.UTF_8));
// Efficiently read large files
Iterators.partition(Files.asCharSource(file, charset).lineIterator(), 1000)
.forEachRemaining(batch -> processBatch(batch));
Summary and Selection Recommendations
Technology Selection Comparison Table
Scenario | Traditional IO Solution | NIO Solution | Third-party Library Solution |
---|---|---|---|
Small file reading/writing | FileInputStream/FileReader | Files.readAllBytes() | FileUtils.readFileToString |
Large file processing | BufferedInputStream | FileChannel + MappedByteBuffer | Guava’s Files utility class |
Object persistence | ObjectOutputStream | ||
Network communication | Socket | Selector + Channel | Netty framework |
Memory operations | ByteArrayOutputStream | ByteBuffer | Guava’s ByteStreams |
Best Practices
Coding Standards: Always specify character encoding (e.g., UTF-8)
new InputStreamReader(fis, StandardCharsets.UTF_8);
Resource Management: Use try-with-resources to ensure automatic closing
try (Socket socket = new Socket(...)) {
// Use the resource
}
Performance Optimization:
- Use buffers (Buffer size is recommended to be 4KB-8KB)
- For large files, prefer NIO’s MappedByteBuffer
- Avoid frequent creation/destruction of stream objects in loops
Exception Handling:
try {
// IO operations
} catch (IOException e) {
log.error("File operation failed: {}", e.getMessage());
throw new CustomException("File processing exception", e);
}