章
目
录
在开发企业应用程序时,有时需要在Java中将文本或二进制数据写入文件,例如将用户生成的报告写入文件系统。
虽然在Java中有多种写文件的方式,但让我们快速浏览一些以备需要时参考。
//快速指引
String content = "some text";
// Java 11
Files.writeString(Path.of("demo.txt"), content);
// 使用Files类
Files.write(Path.of("demo.txt"), content.getBytes());
// 使用BufferedWriter
try (BufferedWriter writer = new BufferedWriter(new FileWriter(filePath.toFile()))) {
writer.write(content);
}
// 使用FileWriter
try(FileWriter fileWriter = new FileWriter(Path.of("demo.txt").toFile())){
fileWriter.write(content);
}
// 写入二进制文件
try(FileOutputStream outputStream = new FileOutputStream(Path.of("demo.txt").toFile())){
byte[] strToBytes = content.getBytes();
outputStream.write(strToBytes);
}
1.使用Files.writeString() – Java 11
从Java 11开始,Files.writeString() 方法提供了一种方便的写入文本到文件的方式。它接受一个Path参数和一个字符串,简化了在单行语句中写入文本内容的过程。
- 顾名思义,writeString() 方法用于将字符/文本数据写入文件。
- 所有字符都按照原样写入,包括换行符。不会添加额外的字符。
- 默认使用UTF-8字符编码。
- 如果在写入或创建文件时发生I/O错误,或者无法使用指定的字符集对文本进行编码,它会抛出IOException。
Path filePath = Path.of("demo.txt");
String content = "hello world !!";
Files.writeString(filePath, content);
2.使用Files.write() 写入文件
Files类是另一种自Java 7以来的写入方法,它与writeString() 类似。它接受一个Path和一个字节数组作为参数。
write() 方法适用于写入二进制数据,也可以用于写入文本数据,如下例所示。
Path filePath = Path.of("demo.txt");
String content = "hello world !!";
//Write bytes
Files.write(filePath, content.getBytes());
//Write lines
List<String> lines = Arrays.asList("a", "b", "c");
Files.write(filePath, lines, StandardCharsets.UTF_8);
3.使用FileChannel和ByteBuffer进行快速写入
FileChannel可用于读取、写入、映射和操作文件。如果我们要写入大文件,FileChannel可能比标准IO更快。
文件通道可安全地供多个并发线程使用。
Path fileName = Path.of("demo.txt");
String content = "hello world !!";
try (
RandomAccessFile stream = new RandomAccessFile(filePath.toFile(),"rw");
FileChannel channel = stream.getChannel();) {
byte[] strBytes = content.getBytes();
ByteBuffer buffer = ByteBuffer.allocate(strBytes.length);
buffer.put(strBytes);
buffer.flip();
channel.write(buffer);
}
4.使用BufferedWriter写入文本文件
BufferedWriter是将内容写入文件的最传统、最简单的方式。它将文本写入字符输出流,以便对单个字符、数组和字符串进行高效写入。
除非需要立即输出,建议在任何写入操作可能昂贵的Writer周围包装一个BufferedWriter,例如FileWriter和OutputStreamWriter,特别是在写入大量数据时。
由于它在写入之前进行了缓冲,所以会减少IO操作,从而提升性能。
Path filePath = Path.of("demo.txt");
String content = "hello world !!";
try (BufferedWriter writer = new BufferedWriter(new FileWriter(filePath.toFile()))) {
writer.write(content);
}
5.使用FileWriter或PrintWriter写入文件
FileWriter是写入文件的最清晰的方式,语法是不言自明的,容易阅读和理解。FileWriter直接写入文件(性能较低)只应在写入次数较少时使用。
因为FileWriter不提供缓冲,所以在写入大量数据时可能会导致性能问题。
Path filePath = Path.of("demo.txt");
String content = "hello world !!";
try(FileWriter fileWriter = new FileWriter(filePath.toFile())){
fileWriter.write(content);
}
使用PrintWriter将格式化文本写入文件。这个类实现了在PrintStream中找到的所有print方法,因此您可以使用与System.out.println()语句相同的所有格式。
Path filePath = Path.of("demo.txt");
String content = "hello world !!";
try(FileWriter fileWriter = new FileWriter(filePath.toFile());
PrintWriter printWriter = new PrintWriter(fileWriter);){
printWriter.print(content);
printWriter.printf("Blog name is %s", "www.panziye.com");
}
6.使用FileOutputStream写入二进制文件
使用FileOutputStream将二进制数据写入文件。FileOutputStream用于写入诸如图像数据之类的原始字节流。对于写入字符流,考虑使用FileWriter。
Path filePath = Path.of("demo.txt");
String content = "hello world !!";
try(FileOutputStream outputStream = new FileOutputStream(filePath.toFile())){
byte[] strToBytes = content.getBytes();
outputStream.write(strToBytes);
}
7.使用DataOutputStream写入文件
DataOutputStream允许应用程序以可移植的方式向输出流写入原始Java数据类型。然后,应用程序可以使用数据输入流来读取数据。
Path filePath = Path.of("demo.txt");
String content = "hello world !!";
try (
FileOutputStream outputStream
= new FileOutputStream(filePath.toFile());
DataOutputStream dataOutStream
= new DataOutputStream(new BufferedOutputStream(outputStream));) {
dataOutStream.writeUTF(content);
dataOutStream.writeInt(10);
dataOutStream.writeLong(100L);
}
8.清晰代码与性能
在考虑性能时,有几个因素需要考虑:
- 便利性:对于写入文本数据,Files.writeString() 是最方便的,而对于二进制数据,Files.write() 是合适的。这些方法提供了易于使用的API。
- 缓冲:BufferedWriter 和 Files.write() 提供了缓冲,可以显著提高写入性能,特别是处理大量数据时。
- 二进制与文本数据:如果需要写入二进制数据,FileOutputStream 是最佳选择。对于文本数据,决定取决于便利性和如上所述的缓冲需求。
对于较小的文件,我们可能更倾向于可读性,因为性能提升将是微不足道的。FileWriter 和 Files.writeString() 应该是较小文件的首选选择。
对于大量数据,我们将需要更好的原始性能。在这种情况下,像BufferedWriter 和 Files.write() 这样的缓冲方法可以提供改进的效率。
最终,方法的选择应该取决于具体的需求,如数据量、简单性和可读性。
9.总结
- 如果尝试写入一个不存在的文件,将首先创建文件,不会抛出异常(除非使用Path方法)。
- 在写入文件内容后始终关闭输出流以释放所有资源。这也有助于防止文件损坏。
- 使用PrintWriter 用于写入格式化文本。
- 使用FileOutputStream 用于写入二进制数据。
- 使用DataOutputStream 用于写入基本数据类型。
- 使用FileChannel 用于写入较大的文件。这也是Java 8中写入文件的首选方式。