Java IO流详解及常用类的代码实例
Java IO(输入输出)流是Java中处理输入和输出操作的核心部分。本文将对常用的Java IO流类进行介绍,并提供一些代码示例来展示它们的使用场景、优缺点。
1. FileInputStream 和 FileOutputStream(推荐)
简介
FileInputStream 和 FileOutputStream 用于以字节流的方式读取和写入文件。这些类适合处理二进制数据,如图像和音频文件。
示例代码
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class FileIOExample {
//读取一个写一次,缺点IO操作频繁(不推荐)
public static void test1(File inputTxtFile, File outputTxtFile){
try(FileInputStream fileInputStream =new FileInputStream(inputTxtFile);
FileOutputStream fileOutputStream=new FileOutputStream(outputTxtFile);) {
int value;
//把读取到得转为0-255得数字,写入到输出流,如果为-1表示到结尾了,停止写入
while ((value=fileInputStream.read())!=-1){
fileOutputStream.write(value);
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
//读取到数组,这样可以减少IO
public static void test2(File inputFile, File outputFile){
try(FileInputStream fileInputStream =new FileInputStream(inputFile);
FileOutputStream fileOutputStream=new FileOutputStream(outputFile);) {
//设置字节数组得大小,一般4K,8k,16K 是比较好的选择。不建议设置得大小是文件得大小,这样如果是大文件,容易导致内存溢出等。对于大文件,仍然使用固定大小的缓冲区是合适的。缓冲区大小设置得合理,可以帮助减少磁盘IO操作的次数,从而提高效率。使用固定大小的缓冲区可以在处理大文件时保持内存使用的稳定性
final byte[] bytes = new byte[4096];
int value;
while ((value=fileInputStream.read(bytes))!=-1){
fileOutputStream.write(bytes,0,value);
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public static void main(String[] args) {
File inputTxtFile = new File("C:\\Users\\15975\\Desktop\\file.txt");
File outputTxtFile = new File("C:\\Users\\15975\\Desktop\\file777.txt");
}
}
使用场景
读取和写入二进制文件(如图片、视频、音频)。
不涉及字符编码转换的场景。
优缺点
优点:
直接处理字节,适用于所有类型的文件。
简单直接的文件复制。
缺点:
不能处理字符编码,需要手动转换字节到字符。
不适合处理文本文件,因为没有缓冲区,性能较低。
2. FileReader 和 FileWriter
简介
FileReader 和 FileWriter 用于以字符流的方式读取和写入文件。这些类适合处理文本数据。
示例代码
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class FileReaderWriterExample {
public static void main(String[] args) {
try (FileReader fr = new FileReader("input.txt");
FileWriter fw = new FileWriter("output.txt")) {
int data;
while ((data = fr.read()) != -1) {
fw.write(data);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
使用场景
处理文本文件(如配置文件、日志文件)。
需要字符编码支持的场景。
优缺点
优点:
自动处理字符编码(FileReader 和 FileWriter 能够自动处理编码,因为它们使用的是平台默认字符编码;它们底层依赖于 InputStreamReader 和 OutputStreamWriter 进行字节与字符之间的转换;为了确保跨平台的一致性和避免编码问题,建议显式指定字符编码)。
适合处理文本数据。
缺点:
不适合处理二进制数据。
没有缓冲,处理大文件时效率低。
3. BufferedReader 和 BufferedWriter(推荐)
简介
BufferedReader 和 BufferedWriter 提供了带缓冲区的字符输入输出流,大幅提高了处理文本文件的效率。
示例代码
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class BufferedReaderWriterExample {
//((不推荐)
public static void test6(File inputFile, File outputFile){
try(BufferedReader fileInputStream =new BufferedReader(new FileReader(inputFile));
BufferedWriter fileOutputStream=new BufferedWriter(new FileWriter(outputFile));) {
String value;
while ((value=fileInputStream.readLine())!=null){
fileOutputStream.write(value);
fileOutputStream.newLine(); // 添加换行符
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
//(强力推荐)只能处理文本、且要求指定编码
public static void test8(File inputFile, File outputFile){
try (InputStreamReader fileInputStream = new InputStreamReader(Files.newInputStream(inputFile.toPath()), StandardCharsets.UTF_8);
OutputStreamWriter fileOutputStream = new OutputStreamWriter(Files.newOutputStream(outputFile.toPath()), StandardCharsets.UTF_8)) {
int value;
while ((value=fileInputStream.read())!=-1){
fileOutputStream.write(value);
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
//(强力推荐)只能处理文本、且要求指定编码、有缓存
public static void test7(File inputFile, File outputFile){
try (BufferedReader fileInputStream = new BufferedReader(new InputStreamReader(Files.newInputStream(inputFile.toPath()), StandardCharsets.UTF_8));
BufferedWriter fileOutputStream = new BufferedWriter(new OutputStreamWriter(Files.newOutputStream(outputFile.toPath()), StandardCharsets.UTF_8))) {
String value;
while ((value=fileInputStream.readLine())!=null){
fileOutputStream.write(value);
fileOutputStream.newLine(); // 添加换行符
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public static void main(String[] args) {
File inputTxtFile = new File("C:\\Users\\15975\\Desktop\\file.txt");
File outputTxtFile = new File("C:\\Users\\15975\\Desktop\\file777.txt");
test6(inputTxtFile,outputTxtFile);
test7(inputTxtFile,outputTxtFile);
}
}
使用场景
处理大文本文件,提高读写效率。
逐行读取和写入文件。
优缺点
优点:
带有缓冲区,处理大文件时效率高。
适合逐行读取和写入。
缺点:
仅适合文本数据。
需要更多的内存来存储缓冲区。
4. DataInputStream 和 DataOutputStream
简介
DataInputStream 和 DataOutputStream 提供了从底层输入流中读取基本数据类型的方法,这些类适合处理一些简单的数据存储和传输。
示例代码
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class DataStreamExample {
public static void main(String[] args) {
try (DataOutputStream dos = new DataOutputStream(new FileOutputStream("data.bin"))) {
dos.writeInt(123);
dos.writeDouble(45.67);
dos.writeUTF("Hello, World!");
} catch (IOException e) {
e.printStackTrace();
}
try (DataInputStream dis = new DataInputStream(new FileInputStream("data.bin"))) {
int intValue = dis.readInt();
double doubleValue = dis.readDouble();
String stringValue = dis.readUTF();
System.out.println("Read values: " + intValue + ", " + doubleValue + ", " + stringValue);
} catch (IOException e) {
e.printStackTrace();
}
}
}
使用场景
读取和写入基本数据类型(二进制格式)。
网络传输或文件存储中的数据序列化。
优缺点
优点:
直接处理基本数据类型,方便高效。
适合网络传输和文件存储中的序列化。
缺点:
仅适合处理基本数据类型,不适合复杂对象。
需要明确的写入和读取顺序。
5. ObjectInputStream 和 ObjectOutputStream
简介
ObjectInputStream 和 ObjectOutputStream 用于读写对象,以实现对象的序列化和反序列化。
示例代码
import java.io.*;
class Person implements Serializable {
private static final long serialVersionUID = 1L;
String name;
int age;
Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Person{name='" + name + "', age=" + age + '}';
}
}
public class ObjectStreamExample {
public static void main(String[] args) {
Person person = new Person("John Doe", 30);
try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("person.dat"))) {
oos.writeObject(person);
} catch (IOException e) {
e.printStackTrace();
}
try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("person.dat"))) {
Person readPerson = (Person) ois.readObject();
System.out.println("Read person: " + readPerson);
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
}
使用场景
对象的持久化存储(如保存应用程序状态)。
网络传输中的对象序列化和反序列化。
优缺点
优点:
支持复杂对象的序列化。
能够在网络传输中使用。
缺点:
必须实现 Serializable 接口。
序列化和反序列化过程可能较慢。
结论
Java IO流提供了多种类来满足不同的输入输出需求。从简单的文件读取和写入,到复杂的对象序列化,每个类都有其特定的使用场景和优缺点。正确选择和使用这些类可以显著提高程序的性能和可靠性。
处理二进制文件、文本、图片、视频、音频等数据,可以使用FileInputStream和FileOutputStream:
1、FileInputStream和FileOutputStream是字节流,适用于处理二进制文件或者不需要进行字符编码转换的文本文件。
2、对于文本文件,如果需要进行字符编码转换,可以在读写过程中使用InputStreamReader和OutputStreamWriter来指定字符编码。
处理大文本类型的文件并考虑缓冲区,可以使用BufferedReader和BufferedWriter:
1、BufferedReader和BufferedWriter是字符流,并且提供了缓冲区功能,可以提高读写的效率。
2、对于大文本文件,使用缓冲区可以减少实际磁盘读写操作的次数,提高性能。
3、在使用BufferedReader和BufferedWriter时,可以选择是否指定字符编码,取决于具体的需求。如果需要进行字符编码转换,可以在构造函数中使用InputStreamReader和OutputStreamWriter来指定字符编码。
1、读取文本文件(使用)
//(强力推荐)只能处理文本、且要求指定编码
public static void test8(File inputFile, File outputFile){
try (InputStreamReader fileInputStream = new InputStreamReader(Files.newInputStream(inputFile.toPath()), StandardCharsets.UTF_8);
OutputStreamWriter fileOutputStream = new OutputStreamWriter(Files.newOutputStream(outputFile.toPath()), StandardCharsets.UTF_8)) {
int value;
while ((value=fileInputStream.read())!=-1){
fileOutputStream.write(value);
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
//(强力推荐)只能处理文本、且要求指定编码、有缓存
public static void test7(File inputFile, File outputFile){
try (BufferedReader fileInputStream = new BufferedReader(new InputStreamReader(Files.newInputStream(inputFile.toPath()), StandardCharsets.UTF_8));
BufferedWriter fileOutputStream = new BufferedWriter(new OutputStreamWriter(Files.newOutputStream(outputFile.toPath()), StandardCharsets.UTF_8))) {
String value;
while ((value=fileInputStream.readLine())!=null){
fileOutputStream.write(value);
fileOutputStream.newLine(); // 添加换行符
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
2、读取图片、视频、音频(使用)
public static void test2(File inputFile, File outputFile) {
try (
BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream(inputFile));
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(new FileOutputStream(outputFile))
) {
final byte[] bytes = new byte[4096];
int value;
while ((value = bufferedInputStream.read(bytes)) != -1) {
bufferedOutputStream.write(bytes, 0, value);
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}