一、简介
Java I/O(输入/输出)是Java编程中非常基础且重要的部分,它允许程序与外部世界进行数据交换。Java I/O操作可以分为两大类:字符流和字节流。以下是一些Java I/O应用中的常用操作:
1. 字节流
- FileInputStream:用于从文件中读取字节数据。
- FileOutputStream:用于将字节数据写入文件。
- BufferedInputStream:提供缓冲区的输入流,提高读取效率。
- BufferedOutputStream:提供缓冲区的输出流,提高写入效率。
- DataInputStream:提供读取Java基本数据类型的方法。
- DataOutputStream:提供写入Java基本数据类型的方法。
- 字符流
- FileReader:用于读取字符文件。
- FileWriter:用于写入字符文件。
- BufferedReader:提供缓冲区的字符输入流,提高读取效率。
- BufferedWriter:提供缓冲区的字符输出流,提高写入效率。
- LineNumberReader:跟踪行号的Reader。
- PrintWriter:提供了便捷的打印方法。
二、核心方法解析
1.InputStream 和 OutputStream
这两个是Java I/O的基础接口,用于处理字节流。
InputStream:
- int read(): 读取一个字节的数据,并返回字节值(0-255),如果到达文件末尾则返回-1。
- int read(byte[] b): 读取最多b.length个字节的数据到字节数组中,并返回实际读取的字节数。
- void close(): 关闭流并释放与之相关联的系统资源。
OutputStream:
- void write(int b): 写入一个字节到输出流中。
- void write(byte[] b): 写入b.length个字节到输出流中。
- void write(byte[] b, int off, int len): 从偏移量off开始,写入len个字节到输出流中。
- void close(): 关闭流并释放与之相关联的系统资源。
2. Reader 和 Writer
这两个接口用于处理字符流,是InputStream和OutputStream的字符版本。
Reader:
- int read(): 读取一个字符并返回其整数值,如果到达文件末尾则返回-1。
- int read(char[] cbuf): 读取字符到字符数组中。
- void close(): 关闭流并释放与之相关联的系统资源。
Writer:
- void write(int c): 写入一个字符到输出流中。
- void write(char[] cbuf): 写入字符数组到输出流中。
- void write(char[] cbuf, int off, int len): 写入字符数组的一部分到输出流中。
- void write(String str): 写入字符串到输出流中。
- void write(String str, int off, int len): 写入字符串的一部分到输出流中。
- void close(): 关闭流并释放与之相关联的系统资源。
三、Java 字节流 实际案例
Java中的字节流主要用于处理二进制数据,如图片、音频、视频等文件的读写操作。以下是几个使用字节流处理实际案例的代码示例:
1.图片复制
此案例演示如何使用FileInputStream和FileOutputStream来复制一张图片。
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class ImageCopyExample {
public static void main(String[] args) {
String sourcePath = "source.jpg";
String targetPath = "target_copy.jpg";
try (FileInputStream fis = new FileInputStream(sourcePath);
FileOutputStream fos = new FileOutputStream(targetPath)) {
//创建一个大小为 1024 字节的缓冲区。这个缓冲区用于在读取和写入文件时暂 存数据。
//使用缓冲区可以提高文件复制的效率,因为它减少了与底层系统的交互次数。
byte[] buffer = new byte[1024];
//定义一个整数变量,用于存储每次从输入流中读取的字节数
int bytesRead;
while ((bytesRead = fis.read(buffer)) != -1) {
fos.write(buffer, 0, bytesRead);
}
System.out.println("图片复制完成");
} catch (IOException e) {
System.err.println("复制过程中发生错误: " + e.getMessage());
}
}
}
通过使用try-with-resources语句,我们不再需要显式地调用close()方法。当try块结束时(无论是正常结束还是因异常退出),资源会自动被关闭,
2. 文件加密/解密(简单示例)
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class OptimizedFileEncryption {
//用于文件加密的偏移量
private static final int OFFSET = 5;
public static void encrypt(String source, String encrypted) throws IOException {
try (FileInputStream fis = new FileInputStream(source);
FileOutputStream fos = new FileOutputStream(encrypted)) {
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = fis.read(buffer)) != -1) {
for (int i = 0; i < bytesRead; i++) {
buffer[i] = (byte) (buffer[i] + OFFSET);
}
fos.write(buffer, 0, bytesRead);
}
}
}
public static void decrypt(String encrypted, String decrypted) throws IOException {
try (FileInputStream fis = new FileInputStream(encrypted);
FileOutputStream fos = new FileOutputStream(decrypted)) {
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = fis.read(buffer)) != -1) {
for (int i = 0; i < bytesRead; i++) {
buffer[i] = (byte) (buffer[i] - OFFSET);
}
fos.write(buffer, 0, bytesRead);
}
}
}
public static void main(String[] args) {
String originalFile = "original.txt";
String encryptedFile = "encrypted.txt";
String decryptedFile = "decrypted.txt";
try {
encrypt(originalFile, encryptedFile);
System.out.println("文件加密完成");
decrypt(encryptedFile, decryptedFile);
System.out.println("文件解密完成");
} catch (IOException e) {
System.err.println("操作过程中发生错误: " + e.getMessage());
}
}
}
3.文件下载(简化示例,不涉及网络编程)
import java.io.*;
public class FileDownloadExample {
// 假设我们有一个“服务器”上的文件内容(实际情况下,这将是网络数据)
private static final byte[] FILE_CONTENT = "This is fake file content for demonstration.".getBytes();
public static void main(String[] args) {
String destinationFilePath = "path/to/downloadedFile.txt";
try (OutputStream outputStream = new FileOutputStream(destinationFilePath)) {
outputStream.write(FILE_CONTENT);
System.out.println("File downloaded successfully!"); // 注意:这只是一个模拟
} catch (IOException e) {
e.printStackTrace();
}
}
}
四、Java 字符流实际案例
1.读取文本文件内容
import java.io.*;
public class ReadTextFile {
public static void main(String[] args) {
String filePath = "example.txt";
try (BufferedReader reader = new BufferedReader(new FileReader(filePath))) {
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
2.复制文本文件
import java.io.*;
public class CopyTextFile {
public static void main(String[] args) {
String sourceFilePath = "source.txt";
String targetFilePath = "target.txt";
try (
BufferedReader reader = new BufferedReader(new FileReader(sourceFilePath));
BufferedWriter writer = new BufferedWriter(new FileWriter(targetFilePath))
) {
String line;
while ((line = reader.readLine()) != null) {
writer.write(line);
writer.newLine(); // 保持原始文件的行格式
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
3. 修改文本文件内容
import java.io.*;
import java.nio.file.*;
public class ModifyTextFile {
public static void main(String[] args) {
String filePath = "example.txt";
// 使用Java 7的Files类和Paths类来读取文件内容
Path path = Paths.get(filePath);
List<String> lines = null;
try {
lines = Files.readAllLines(path);
} catch (IOException e) {
e.printStackTrace();
}
if (lines != null) {
for (int i = 0; i < lines.size(); i++) {
// 假设我们要将文件中的"old"替换为"new"
if (lines.get(i).contains("old")) {
lines.set(i, lines.get(i).replace("old", "new"));
}
}
try (BufferedWriter writer = new BufferedWriter(new FileWriter(filePath))) {
for (String line : lines) {
writer.write(line);
writer.newLine();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}