在Java的IO体系中,FileInputStream和FileOutputStream是用于处理字节流的文件操作类,前者用于从文件中读取字节数据,后者用于将字节数据写入文件,两者配合使用可以完成大多数基础的文件读写需求。

FileInputStream的基本用法
FileInputStream用于读取文件内容,构造方法可以接收文件路径字符串或者File对象作为参数。读取操作有单次读取单个字节和批量读取字节数组两种方式,读取完成后需要关闭流释放资源。
单次读取单个字节
read()方法每次读取一个字节,返回值是读取到的字节对应的整数,当返回-1时表示已经读到文件末尾。
import java.io.FileInputStream;
import java.io.IOException;
public class FileInputStreamDemo {
public static void main(String[] args) {
FileInputStream fis = null;
try {
// 创建FileInputStream对象,指定要读取的文件路径
fis = new FileInputStream("test.txt");
int byteData;
// 循环读取,直到返回-1
while ((byteData = fis.read()) != -1) {
// 将读取到的字节转换为字符输出,这里仅作示例,实际处理需根据文件编码调整
System.out.print((char) byteData);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
// 关闭流,避免资源泄漏
if (fis != null) {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
批量读取字节数组
read(byte[] b)方法会将读取到的字节存入传入的字节数组中,返回值是实际读取到的字节数,同样返回-1表示读到末尾,这种方式比单次读取效率更高。
import java.io.FileInputStream;
import java.io.IOException;
public class FileInputStreamBatchDemo {
public static void main(String[] args) {
try (FileInputStream fis = new FileInputStream("test.txt")) {
// 创建缓冲区字节数组,大小通常设置为1024或8192
byte[] buffer = new byte[1024];
int length;
// 批量读取,length为实际读取的字节数
while ((length = fis.read(buffer)) != -1) {
// 将读取到的字节转换为字符串输出,指定UTF-8编码避免乱码
String content = new String(buffer, 0, length, "UTF-8");
System.out.print(content);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
上面的代码使用了try-with-resources语法,Java会自动在代码块结束后关闭实现了AutoCloseable接口的资源,不需要手动在finally中关闭流,代码更简洁。
FileOutputStream的基本用法
FileOutputStream用于向文件写入数据,构造方法可以指定文件路径,还可以通过第二个布尔参数指定是否以追加模式写入,默认是覆盖模式。
写入单个字节
write(int b)方法可以将指定的字节写入文件,传入的整数会被转换为低8位的字节写入。
import java.io.FileOutputStream;
import java.io.IOException;
public class FileOutputStreamDemo {
public static void main(String[] args) {
try (FileOutputStream fos = new FileOutputStream("output.txt")) {
// 写入单个字节,这里是字符a对应的ASCII码
fos.write(97);
// 也可以直接写入字符,会自动转换为对应的字节
fos.write('b');
} catch (IOException e) {
e.printStackTrace();
}
}
}
批量写入字节数组
write(byte[] b)方法可以将整个字节数组写入文件,write(byte[] b, int off, int len)可以写入字节数组从off位置开始的len个字节。
import java.io.FileOutputStream;
import java.io.IOException;
public class FileOutputStreamBatchDemo {
public static void main(String[] args) {
try (FileOutputStream fos = new FileOutputStream("output.txt", true)) {
// 追加模式写入,第二个参数为true
String content = "hello java io";
// 将字符串转换为字节数组写入
byte[] bytes = content.getBytes("UTF-8");
fos.write(bytes);
// 也可以指定写入部分字节
fos.write(bytes, 0, 5);
} catch (IOException e) {
e.printStackTrace();
}
}
}
FileInputStream与FileOutputStream配合复制文件
两个流配合使用可以完成文件复制的操作,从源文件读取字节,再写入目标文件即可。
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class FileCopyDemo {
public static void main(String[] args) {
String sourcePath = "source.jpg";
String targetPath = "target.jpg";
try (FileInputStream fis = new FileInputStream(sourcePath);
FileOutputStream fos = new FileOutputStream(targetPath)) {
byte[] buffer = new byte[1024];
int length;
while ((length = fis.read(buffer)) != -1) {
// 将读取到的字节写入目标文件
fos.write(buffer, 0, length);
}
System.out.println("文件复制完成");
} catch (IOException e) {
e.printStackTrace();
}
}
}
使用注意事项
- 文件路径如果不存在,FileInputStream会抛出FileNotFoundException,而FileOutputStream会自动创建新的文件,但是如果父目录不存在则会抛出异常。
- 读取文本文件时需要注意编码问题,如果文件和代码使用的编码不一致,直接转换字符串会出现乱码,需要指定对应的编码格式。
- 流使用完成后必须关闭,否则会导致资源泄漏,推荐使用try-with-resources语法自动关闭资源。
- 缓冲区的大小可以根据实际需求调整,通常设置为2的次幂,比如1024、4096、8192等,过大的缓冲区会占用更多内存。
常见问题解答
为什么读取中文文本会出现乱码
因为FileInputStream是字节流,读取中文等多字节字符时,单个字节转换会丢失信息,如果是文本文件建议使用FileReader和FileWriter字符流,或者在读取字节后使用正确的编码转换字符串。
复制大文件时效率很低怎么办
可以增大缓冲区的大小,或者使用BufferedInputStream和BufferedOutputStream包装流,这两个类内置了缓冲区,能提升读写效率。
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class BufferedCopyDemo {
public static void main(String[] args) {
try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream("bigfile.zip"));
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("bigfile_copy.zip"))) {
byte[] buffer = new byte[8192];
int length;
while ((length = bis.read(buffer)) != -1) {
bos.write(buffer, 0, length);
}
System.out.println("大文件复制完成");
} catch (IOException e) {
e.printStackTrace();
}
}
}
FileInputStreamFileOutputStreamJava_IO文件读写修改时间:2026-07-03 20:33:16