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:

MethodDescriptionExample
System.out.print()Output content without line breakprint(“Hello”)
System.out.println()Output content with automatic line breakprintln(“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:

MethodDescriptionExample 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

ScenarioTraditional IO SolutionNIO SolutionThird-party Library Solution
Small file reading/writingFileInputStream/FileReaderFiles.readAllBytes()FileUtils.readFileToString
Large file processingBufferedInputStreamFileChannel + MappedByteBufferGuava’s Files utility class
Object persistenceObjectOutputStream
Network communicationSocketSelector + ChannelNetty framework
Memory operationsByteArrayOutputStreamByteBufferGuava’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);
}
Avatar

By BytePilot

Because sharing makes us better. Let’s learn, build, and grow — one byte at a time.

Leave a Reply

Your email address will not be published. Required fields are marked *