1. 字符流与字节流
Java中的IO流分为字符流和字节流。两者的主要区别在于处理数据的方式。
- 字符流:用于处理字符数据,以字符为单位进行读写。适用于文本文件的读写。
- 主要类:
FileReader
、FileWriter
、BufferedReader
、BufferedWriter
。
- 主要类:
- 字节流:用于处理字节数据,以字节为单位进行读写。适用于音频、图像等非文本文件的读写。
- 主要类:
FileInputStream
、FileOutputStream
、BufferedInputStream
、BufferedOutputStream
。
- 主要类:
示例代码
字符流示例:
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.BufferedWriter;
import java.io.IOException;
public class CharStreamExample {
public static void main(String[] args) {
// 写入文本文件
try (BufferedWriter writer = new BufferedWriter(new FileWriter("example.txt"))) {
writer.write("Hello, World! 你好,世界!");
} catch (IOException e) {
e.printStackTrace();
}
// 读取文本文件
try (BufferedReader reader = new BufferedReader(new FileReader("example.txt"))) {
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
字节流示例:
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class ByteStreamExample {
public static void main(String[] args) {
// 写入字节文件
try (FileOutputStream fos = new FileOutputStream("example.bin")) {
fos.write(new byte[]{65, 66, 67}); // 写入字节数据
} catch (IOException e) {
e.printStackTrace();
}
// 读取字节文件
try (FileInputStream fis = new FileInputStream("example.bin")) {
int data;
while ((data = fis.read()) != -1) {
System.out.print((char) data); // 打印读取到的字节数据
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
2. 中文字符存储处理
在处理中文字符时,需要确保文件的编码格式正确。通常使用UTF-8编码来存储中文字符。
字符流中的中文处理:
import java.io.*;
public class ChineseCharExample {
public static void main(String[] args) {
try (BufferedWriter writer = new BufferedWriter(new FileWriter("chinese.txt", StandardCharsets.UTF_8))) {
writer.write("这是中文内容。");
} catch (IOException e) {
e.printStackTrace();
}
try (BufferedReader reader = new BufferedReader(new FileReader("chinese.txt", StandardCharsets.UTF_8))) {
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
3. 字节流对音频和图像的处理
字节流适用于处理音频、图像等非文本文件。以下是读取和写入音频文件的示例。
音频文件处理示例:
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class AudioFileExample {
public static void main(String[] args) {
// 复制音频文件
try (FileInputStream fis = new FileInputStream("source_audio.mp3");
FileOutputStream fos = new FileOutputStream("destination_audio.mp3")) {
byte[] buffer = new byte[1024];
int length;
while ((length = fis.read(buffer)) > 0) {
fos.write(buffer, 0, length);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
4.文件存储与读取
在Java中,文件的存储与读取主要使用FileInputStream
、FileOutputStream
、FileReader
和FileWriter
等类。以下是不同的示例,展示了如何使用这些类进行文件操作。
1. 使用字节流进行文件存储与读取
字节流适用于处理二进制文件,如音频、图像等。下面的示例展示了如何使用FileInputStream
和FileOutputStream
进行文件的读写操作。
示例代码:
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class ByteStreamFileExample {
public static void main(String[] args) {
// 写入文件
try (FileOutputStream fos = new FileOutputStream("output.bin")) {
String data = "Hello, World!";
fos.write(data.getBytes()); // 将字符串数据转换为字节并写入文件
} catch (IOException e) {
e.printStackTrace(); // 捕获并打印IO异常
}
// 读取文件
try (FileInputStream fis = new FileInputStream("output.bin")) {
int byteData;
while ((byteData = fis.read()) != -1) {
System.out.print((char) byteData); // 读取字节并转换为字符
}
} catch (IOException e) {
e.printStackTrace(); // 捕获并打印IO异常
}
}
}
代码注释:
FileOutputStream
用于将数据写入指定的文件。write(byte[])
方法将字节数组写入文件。FileInputStream
用于从文件中读取字节。read()
方法逐个读取字节,直到文件末尾(返回值为-1)。
2. 使用字符流进行文件存储与读取
字符流适用于处理文本文件,能够直接处理字符数据。下面的示例展示了如何使用FileReader
和FileWriter
进行文本文件的读写操作。
示例代码:
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class CharStreamFileExample {
public static void main(String[] args) {
// 写入文件
try (BufferedWriter writer = new BufferedWriter(new FileWriter("output.txt"))) {
writer.write("Hello, World! 你好,世界!"); // 写入字符串到文件
} catch (IOException e) {
e.printStackTrace(); // 捕获并打印IO异常
}
// 读取文件
try (BufferedReader reader = new BufferedReader(new FileReader("output.txt"))) {
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line); // 逐行读取文件内容并打印
}
} catch (IOException e) {
e.printStackTrace(); // 捕获并打印IO异常
}
}
}
- 字节流适用于处理二进制数据(如音频、图像)。使用
FileInputStream
和FileOutputStream
进行读写。 - 字符流适用于处理文本数据。使用
FileReader
和FileWriter
进行读写,通常配合BufferedReader
和BufferedWriter
提高性能。
5. 异常处理
在Java中处理IO异常时,可以使用try-catch
语句块。try-with-resources
语句可以自动关闭资源。
异常处理示例:
import java.io.*;
public class ExceptionHandlingExample {
public static void main(String[] args) {
// 处理文件读写异常
try (BufferedReader reader = new BufferedReader(new FileReader("nonexistent.txt"))) {
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
} catch (FileNotFoundException e) {
System.err.println("File not found: " + e.getMessage());
} catch (IOException e) {
System.err.println("IO exception: " + e.getMessage());
}
}
}
6. 自定义异常
自定义异常可以帮助你更好地描述特定的错误情况。
自定义异常示例:
class CustomIOException extends Exception {
public CustomIOException(String message) {
super(message);
}
}
public class CustomExceptionExample {
public static void main(String[] args) {
try {
throw new CustomIOException("This is a custom IO exception.");
} catch (CustomIOException e) {
System.err.println(e.getMessage());
}
}
}
7. try
, catch
, finally
try
:尝试执行可能抛出异常的代码块。catch
:捕获并处理异常。finally
:无论是否发生异常,都执行的代码块(用于清理资源)。
try-catch-finally
示例:
public class TryCatchFinallyExample {
public static void main(String[] args) {
FileInputStream fis = null;
try {
fis = new FileInputStream("example.txt");
int data = fis.read();
System.out.println((char) data);
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fis != null) {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
8. throw
和 throws
throw
:用于在方法内部显式抛出异常。throws
:用于在方法声明中指示该方法可能抛出异常,调用者需要处理这些异常。
throw
和throws
示例:
public class ThrowThrowsExample {
// 使用throws在方法签名中声明异常
public static void main(String[] args) throws IOException {
try {
readFile("nonexistent.txt");
} catch (IOException e) {
e.printStackTrace();
}
}
// 使用throw在方法内部抛出异常
public static void readFile(String fileName) throws IOException {
if ("nonexistent.txt".equals(fileName)) {
throw new IOException("File does not exist.");
}
// 其他文件处理代码
}
}
9. try-with-resources
try-with-resources
语句用于自动关闭实现了AutoCloseable
接口的资源,如文件流。它可以简化资源的管理,并避免漏关闭资源的问题。
try-with-resources
示例:
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class TryWithResourcesExample {
public static void main(String[] args) {
try (BufferedReader reader = new BufferedReader(new FileReader("example.txt"))) {
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
总结
- 字符流适用于文本文件处理,而字节流适用于音频、图像等二进制文件处理。
- 处理中文字符时,需要使用合适的编码(如UTF-8)。
- 使用字节流处理音频和图像文件时,可以直接读取和写入字节数据。
- 在文件操作中,使用
try-catch
语句处理异常,使用try-with-resources
简化资源管理。 - 自定义异常可以帮助处理特定的错误情况。