Java I/O

Java I/O (Input/Output) 详解

Java I/O 是 Java 编程的重要组成部分,它提供了一套丰富的 API 用于处理各种输入和输出操作。本文将详细介绍 Java I/O 的基本概念、主要 API 的使用方法以及常见的应用场景。

一、Java I/O 概述

1.1 什么是 I/O

I/O 是 Input/Output(输入/输出)的缩写,指的是程序与外部环境进行数据交换的操作。输入操作从外部资源读取数据到程序中,输出操作将数据从程序写入到外部资源中。外部资源可以是文件、网络、控制台、设备等。

1.2 Java I/O 的分类

Java I/O 一般分为以下几类:

  • 基础 I/O:包括字节流(InputStream 和 OutputStream)和字符流(Reader 和 Writer)。
  • 高级 I/O:包括缓冲流、数据流、对象流等。
  • 基于 NIO(New I/O)的 I/O 操作。

二、字节流 API

字节流是最基本的 I/O 操作,主要用于处理二进制数据。字节流的基类主要有 InputStreamOutputStream

2.1 输入字节流(InputStream)

InputStream 是所有字节输入流的超类,提供了读取字节的方法。

常用子类:
  • FileInputStream
  • ByteArrayInputStream
  • FilterInputStream
常用方法:
 

java

public abstract class InputStream { public abstract int read() throws IOException; public int read(byte[] b) throws IOException; public int read(byte[] b, int off, int len) throws IOException; public void close() throws IOException; }

示例:
 

java

import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; public class InputStreamExample { public static void main(String[] args) { try (InputStream inputStream = new FileInputStream("example.txt")) { int data; while ((data = inputStream.read()) != -1) { System.out.print((char) data); } } catch (IOException e) { e.printStackTrace(); } } }

2.2 输出字节流(OutputStream)

OutputStream 是所有字节输出流的超类,提供了写出字节的方法。

常用子类:
  • FileOutputStream
  • ByteArrayOutputStream
  • FilterOutputStream
常用方法:
 

java

public abstract class OutputStream { public abstract void write(int b) throws IOException; public void write(byte[] b) throws IOException; public void write(byte[] b, int off, int len) throws IOException; public void close() throws IOException; }

示例:
 

java

import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; public class OutputStreamExample { public static void main(String[] args) { try (OutputStream outputStream = new FileOutputStream("example.txt")) { String data = "Hello, world!"; outputStream.write(data.getBytes()); } catch (IOException e) { e.printStackTrace(); } } }

三、字符流 API

字符流是专门用于处理字符数据的 I/O 操作。字符流的基类主要有 ReaderWriter

3.1 输入字符流(Reader)

Reader 是所有字符输入流的超类,提供了读取字符的方法。

常用子类:
  • FileReader
  • BufferedReader
  • InputStreamReader
常用方法:
 

java

public abstract class Reader { public abstract int read() throws IOException; public int read(char[] cbuf) throws IOException; public int read(char[] cbuf, int off, int len) throws IOException; public void close() throws IOException; }

示例:
 

java

import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; import java.io.Reader; public class ReaderExample { public static void main(String[] args) { try (Reader reader = new FileReader("example.txt"); BufferedReader bufferedReader = new BufferedReader(reader)) { String line; while ((line = bufferedReader.readLine()) != null) { System.out.println(line); } } catch (IOException e) { e.printStackTrace(); } } }

3.2 输出字符流(Writer)

Writer 是所有字符输出流的超类,提供了写出字符的方法。

常用子类:
  • FileWriter
  • BufferedWriter
  • OutputStreamWriter
常用方法:
 

java

public abstract class Writer { public abstract void write(int c) throws IOException; public void write(char[] cbuf) throws IOException; public void write(char[] cbuf, int off, int len) throws IOException; public void write(String str) throws IOException; public void close() throws IOException; }

示例:
 

java

import java.io.BufferedWriter; import java.io.FileWriter; import java.io.IOException; import java.io.Writer; public class WriterExample { public static void main(String[] args) { try (Writer writer = new FileWriter("example.txt"); BufferedWriter bufferedWriter = new BufferedWriter(writer)) { String data = "Hello, world!"; bufferedWriter.write(data); } catch (IOException e) { e.printStackTrace(); } } }

四、缓冲流

缓冲流提供了一个缓冲区,显著提升了 I/O 的效率。常用的缓冲流包括 BufferedInputStreamBufferedOutputStreamBufferedReaderBufferedWriter

4.1 缓冲字节输入流(BufferedInputStream)

 

java

import java.io.BufferedInputStream; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; public class BufferedInputStreamExample { public static void main(String[] args) { try (InputStream inputStream = new FileInputStream("example.txt"); BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream)) { int data; while ((data = bufferedInputStream.read()) != -1) { System.out.print((char) data); } } catch (IOException e) { e.printStackTrace(); } } }

4.2 缓冲字节输出流(BufferedOutputStream)

 

java

import java.io.BufferedOutputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; public class BufferedOutputStreamExample { public static void main(String[] args) { try (OutputStream outputStream = new FileOutputStream("example.txt"); BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(outputStream)) { String data = "Hello, world!"; bufferedOutputStream.write(data.getBytes()); } catch (IOException e) { e.printStackTrace(); } } }

4.3 缓冲字符输入流(BufferedReader)

上面的 ReaderExample 已经展示了如何使用 BufferedReader,再来看一个读取文件中所有行并存入列表的例子:

 

java

import java.io.*; import java.util.*; public class BufferedReaderExample { public static void main(String[] args) { List<String> lines = new ArrayList<>(); try (Reader reader = new FileReader("example.txt"); BufferedReader bufferedReader = new BufferedReader(reader)) { String line; while ((line = bufferedReader.readLine()) != null) { lines.add(line); } } catch (IOException e) { e.printStackTrace(); } for (String line : lines) { System.out.println(line); } } }

4.4 缓冲字符输出流(BufferedWriter)

上面的 WriterExample 已经展示了如何使用 BufferedWriter,再来看一个写入多行文本的例子:

 

java

import java.io.*; import java.util.*; public class BufferedWriterExample { public static void main(String[] args) { List<String> lines = Arrays.asList("First Line", "Second Line", "Third Line"); try (Writer writer = new FileWriter("example.txt"); BufferedWriter bufferedWriter = new BufferedWriter(writer)) { for (String line : lines) { bufferedWriter.write(line); bufferedWriter.newLine(); } } catch (IOException e) { e.printStackTrace(); } } }

五、数据流

数据流用于读写基本数据类型(如 intfloatdouble)和 String 类型。

数据输入流(DataInputStream)

 

java

import java.io.DataInputStream; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; public class DataInputStreamExample { public static void main(String[] args) { try (InputStream inputStream = new FileInputStream("example.dat"); DataInputStream dataInputStream = new DataInputStream(inputStream)) { int intValue = dataInputStream.readInt(); float floatValue = dataInputStream.readFloat(); String strValue = dataInputStream.readUTF(); System.out.println("Integer: " + intValue); System.out.println("Float: " + floatValue); System.out.println("String: " + strValue); } catch (IOException e) { e.printStackTrace(); } } }

数据输出流(DataOutputStream)

 

java

import java.io.DataOutputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; public class DataOutputStreamExample { public static void main(String[] args) { try (OutputStream outputStream = new FileOutputStream("example.dat"); DataOutputStream dataOutputStream = new DataOutputStream(outputStream)) { dataOutputStream.writeInt(123); dataOutputStream.writeFloat(45.67f); dataOutputStream.writeUTF("Hello, DataOutputStream!"); } catch (IOException e) { e.printStackTrace(); } } }

六、对象流

对象流用于序列化和反序列化对象,对象流的主要类是 ObjectInputStreamObjectOutputStream

对象输入流(ObjectInputStream)

 

java

import java.io.FileInputStream; import java.io.IOException; import java.io.ObjectInputStream; public class ObjectInputStreamExample { public static void main(String[] args) { try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("example.obj"))) { Student student = (Student) ois.readObject(); System.out.println("Name: " + student.getName()); System.out.println("Age: " + student.getAge()); } catch (IOException | ClassNotFoundException e) { e.printStackTrace(); } } }

对象输出流(ObjectOutputStream)

 

java

import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectOutputStream; public class ObjectOutputStreamExample { public static void main(String[] args) { try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("example.obj"))) { Student student = new Student("John Doe", 22); oos.writeObject(student); } catch (IOException e) { e.printStackTrace(); } } }

示例对象类(Student)

 

java

import java.io.Serializable; public class Student implements Serializable { private static final long serialVersionUID = 1L; private String name; private int age; public Student(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public int getAge() { return age; } }

七、NIO(新 I/O)

NIO(New I/O)是 Java 1.4 引入的一组新的 I/O API,能够提供非阻塞 I/O 操作,拥有比传统 I/O 更高的性能和更复杂的功能。NIO 主要组件包括 ChannelBufferSelector

7.1 通道(Channel)

通道是 I/O 操作的载体,可以用于读取和写入数据。

示例:FileChannel
 

java

import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.nio.ByteBuffer; import java.nio.channels.FileChannel; public class FileChannelExample { public static void main(String[] args) { try (FileChannel fileChannel = new FileInputStream("source.txt").getChannel(); FileChannel targetChannel = new FileOutputStream("target.txt").getChannel()) { ByteBuffer buffer = ByteBuffer.allocate(1024); int bytesRead; while ((bytesRead = fileChannel.read(buffer)) != -1) { buffer.flip(); // 切换到读取模式 targetChannel.write(buffer); buffer.clear(); // 清空缓冲区以便下次写入 } } catch (IOException e) { e.printStackTrace(); } } }

7.2 缓冲区(Buffer)

缓冲区是在数据传输中临时存储数据的地方,NIO 的核心概念之一。

示例:ByteBuffer
 

java

import java.nio.ByteBuffer; public class ByteBufferExample { public static void main(String[] args) { ByteBuffer buffer = ByteBuffer.allocate(256); buffer.put((byte) 'H'); buffer.put((byte) 'e'); buffer.put((byte) 'l'); buffer.put((byte) 'l'); buffer.put((byte) 'o'); buffer.flip(); // 将缓冲区切换到读取模式 while (buffer.hasRemaining()) { System.out.print((char) buffer.get()); } } }

7.3 选择器(Selector)

选择器用于管理多个通道,可以用于处理非阻塞 I/O 操作。 示例如下:

 

java

public class SelectorExample { public static void main(String[] args) { try (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> selectedKeys = selector.selectedKeys(); Iterator<SelectionKey> iter = selectedKeys.iterator(); while (iter.hasNext()) { SelectionKey key = iter.next(); if (key.isAcceptable()) { // 接受连接请求 ServerSocketChannel server = (ServerSocketChannel) key.channel(); SocketChannel client = server.accept(); client.configureBlocking(false); client.register(selector, SelectionKey.OP_READ); } else if (key.isReadable()) { // 处理读请求 SocketChannel client = (SocketChannel) key.channel(); ByteBuffer buffer = ByteBuffer.allocate(256); int bytesRead = client.read(buffer); if (bytesRead == -1) { client.close(); } else { buffer.flip(); while (buffer.hasRemaining()) { System.out.print((char) buffer.get()); } } } iter.remove(); // 移除已处理的键 } } } catch (IOException e) { e.printStackTrace(); } } }

八、常见场景及应用

8.1 文件读写

处理文件读写是最常见的 I/O 操作,使用 FileInputStream、FileOutputStream、FileReader 和 FileWriter 等类即可完成。

8.2 序列化与反序列化

使用 ObjectInputStream 和 ObjectOutputStream,可以轻松实现对象的序列化和反序列化,适用于保存对象的状态或远程传输对象。

8.3 缓冲读写

为提升 I/O 性能,Buffer流如 BufferedReader 和 BufferedWriter 是常用工具,适用于读写大量数据或频繁 I/O 操作的场景。

8.4 网络编程

NIO 的通道(Channel)和选择器(Selector)机制非常适合非阻塞的高性能网络编程,如处理多客户端连接的服务器。

8.5 数据流

使用 DataInputStream 和 DataOutputStream 可以方便地读写基本数据类型和字符串,适用于需要进行数据交换或通讯的场景,如网络协议实现。

  • 13
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值