Java IO:使用FileOutputStream进行文件写入与复制,以及try-with-resources语句
Java 的 FileOutputStream 类是用于向文件写入字节数据的输出流。它提供了多种构造方法来初始化文件输出操作:
FileOutputStream(String name): 创建一个指向指定文件路径的输出流。如果文件已存在,则会清空文件内容;如果文件不存在,则会创建新文件。FileOutputStream(String name, boolean append): 在上述构造方法的基础上,增加了append参数。若append为true,则数据会追加到文件末尾;若为false(或省略),则会覆盖原有内容。
FileOutputStream 的核心写入方法包括:
write(int b): 写入单个字节。write(byte[] b): 将整个字节数组的数据写入文件。write(byte[] b, int off, int len): 将字节数组中从偏移量off开始的len个字节写入文件。close(): 关闭流,释放相关系统资源。flush(): 刷新此输出流,强制将所有缓冲的输出字节写入文件。
演示 write() 方法
以下示例展示了如何使用 FileOutputStream 的 write() 方法向文件写入数据:
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
public class FileWriteDemo {
public static void main(String[] args) {
OutputStream os = null;
try {
// 以覆盖模式打开文件
os = new FileOutputStream("output.txt");
os.write(97); // 写入 ASCII 码为 97 的字符 'a'
os.write('\n'); // 写入换行符
os.write("Hello".getBytes()); // 写入字符串 "Hello"
os.write(" World".getBytes()); // 写入字符串 " World"
os.write(" Java".getBytes()); // 写入字符串 " Java"
} catch (IOException e) {
System.err.println("文件写入时发生错误: " + e.getMessage());
e.printStackTrace();
} finally {
if (os != null) {
try {
os.close(); // 关闭流
} catch (IOException e) {
System.err.println("关闭输出流时发生错误: " + e.getMessage());
throw new RuntimeException("Failed to close stream", e);
}
}
}
}
}
文件复制示例
使用 FileInputStream 读取数据,然后通过 FileOutputStream 写入数据,可以实现文件的复制功能。以下示例演示了如何复制一个文件:
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class FileCopyExample {
public static void main(String[] args) {
FileInputStream fis = null;
FileOutputStream fos = null;
byte[] buffer = new byte[1024]; // 缓冲区,用于分块读写
try {
fis = new FileInputStream("source.pdf"); // 源文件路径
// 目标文件路径,true表示追加模式,可根据需求修改
fos = new FileOutputStream("destination.pdf", false);
int bytesRead;
// 循环读取源文件内容,直到文件末尾
while ((bytesRead = fis.read(buffer)) != -1) {
fos.write(buffer, 0, bytesRead); // 将读取到的字节写入目标文件
}
System.out.println("文件复制成功!");
} catch (IOException e) {
System.err.println("文件复制过程中发生错误: " + e.getMessage());
throw new RuntimeException("File copy operation failed", e);
} finally {
// 确保流被正确关闭
closeStream(fis);
closeStream(fos);
}
}
// 辅助方法,用于安全关闭流
private static void closeStream(java.io.Closeable stream) {
if (stream != null) {
try {
stream.close();
} catch (IOException e) {
System.err.println("关闭流时发生错误: " + e.getMessage());
}
}
}
}
使用 try-with-resources 语句
为了简化资源管理(特别是资源的关闭),Java 提供了 try-with-resources 语句(TWR)。它能确保在 try 块执行完毕后(无论是否发生异常),自动调用实现了 AutoCloseable 接口的资源对象的 close() 方法。这大大减少了手动编写 finally 块来关闭资源的需要。
在 TWR 语句中声明的资源:
- 其作用域被限制在
try块内部。 - 声明的资源对象必须实现
AutoCloseable接口。Java 的 IO 流类(如InputStream,OutputStream,Reader,Writer等)都实现了该接口。 - 可以在括号内声明一个或多个资源,用分号分隔。
以下示例展示了如何使用 try-with-resources 来进行文件复制,省去了手动关闭流的代码:
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class TryWithResourcesFileCopy {
public static void main(String[] args) {
String sourceFilePath = "source_document.pdf";
String destFilePath = "copied_document.pdf";
try (
// 声明输入流,自动实现 AutoCloseable
InputStream inputStream = new FileInputStream(sourceFilePath);
// 声明输出流,指定追加模式(true)或覆盖模式(false)
OutputStream outputStream = new FileOutputStream(destFilePath, false)
) {
byte[] dataBuffer = new byte[1024];
int bytesRead;
// 读取并写入数据
while ((bytesRead = inputStream.read(dataBuffer)) != -1) {
outputStream.write(dataBuffer, 0, bytesRead);
}
System.out.println("文件已成功复制到 " + destFilePath + ",使用 try-with-resources。");
} catch (IOException e) {
System.err.println("使用 try-with-resources 进行文件复制时发生错误: " + e.getMessage());
throw new RuntimeException("File copy with TWR failed", e);
}
// 此处无需手动关闭 inputStream 和 outputStream,Java 会自动处理
}
}