java中文件读写本质是数据流的进出,主要通过传统io和nio.2两种方式实现;传统io基于流,使用fileinputstream/filereader和fileoutputstream/filewriter配合缓冲流进行读写,适合简单任务,而nio.2基于path和files工具类,提供更现代、高效、功能丰富的api,推荐用于现代开发;1. 读写文本文件应优先使用bufferedreader/bufferedwriter或nio.2的files.readstring/writestring,并明确指定standardcharsets.utf_8编码避免乱码;2. 必须使用try-with-resources确保流自动关闭,防止资源泄露;3. 性能优化关键是使用缓冲流减少i/o操作,避免频繁flush,对大文件可考虑内存映射;4. 常见陷阱包括未关闭流、编码不一致、直接使用非缓冲流和路径处理不当;5. nio.2支持高级操作如文件复制移动(files.copy/move)、属性读取(files.readattributes)、目录遍历(files.walk)、临时文件创建和文件系统监控(watchservice),功能更强大且代码更简洁;因此,对于新项目应优先选择nio.2,传统io适用于简单场景或维护旧代码。

Java中操作文件进行读写,本质上就是数据流的进出。你可以想象成给文件开辟一个通道,然后把数据倒进去(写),或者从里面舀出来(读)。这其中,Java提供了好几套API来做这件事,从经典的IO流到后来更现代的NIO.2,各有侧重,但核心都是围绕着数据的传输。
要进行文件读写,我们通常会用到字节流(处理所有类型数据)或字符流(专门处理文本数据)。对于文本文件,我个人更倾向于使用字符流,因为它能更好地处理字符编码问题。
写入文件:
立即学习“Java免费学习笔记(深入)”;
最常见且推荐的做法是使用
FileWriter
BufferedWriter
FileOutputStream
BufferedOutputStream
BufferedWriter
BufferedOutputStream
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.io.FileOutputStream;
import java.io.BufferedOutputStream;
import java.nio.charset.StandardCharsets; // 推荐指定编码
public class FileWriteExample {
public static void main(String[] args) {
// 写入文本文件
String textContent = "你好,世界!\n这是Java文件写入的示例。\n再来一行。";
try (BufferedWriter writer = new BufferedWriter(new FileWriter("myTextFile.txt", StandardCharsets.UTF_8))) {
// true 表示追加模式,如果文件不存在则创建
// 默认是覆盖模式。这里我直接在FileWriter里指定了编码和追加模式
// 对于FileWriter直接指定Charset,需要Java 11+ 或者使用OutputStreamWriter
// 更标准的方式是:
// new BufferedWriter(new OutputStreamWriter(new FileOutputStream("myTextFile.txt", true), StandardCharsets.UTF_8))
// 不过对于简单的文本写入,FileWriter(String fileName, boolean append) 配合默认编码也行
// 但为了编码安全,我更推荐明确指定。
// 简单起见,我这里先用一个常见的FileWriter构造器,但心里要知道编码问题。
// 实际上,更推荐的文本写入方式是NIO.2的Files.writeString
// Files.writeString(Path.of("myTextFileNIO.txt"), textContent, StandardOpenOption.CREATE, StandardOpenOption.APPEND);
// 这里我们先专注于传统IO
writer.write(textContent);
System.out.println("文本内容已写入 myTextFile.txt");
} catch (IOException e) {
System.err.println("写入文本文件时发生错误: " + e.getMessage());
}
// 写入二进制文件 (例如,一个简单的字节序列)
byte[] binaryData = {0x01, 0x02, 0x03, 0x04, 0x05, 0x0A, 0x0B};
try (BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("myBinaryFile.bin"))) {
bos.write(binaryData);
System.out.println("二进制内容已写入 myBinaryFile.bin");
} catch (IOException e) {
System.err.println("写入二进制文件时发生错误: " + e.getMessage());
}
}
}读取文件:
读取文件与写入类似,使用
FileReader
BufferedReader
FileInputStream
BufferedInputStream
BufferedReader
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.FileInputStream;
import java.io.BufferedInputStream;
import java.nio.charset.StandardCharsets; // 推荐指定编码
public class FileReadExample {
public static void main(String[] args) {
// 读取文本文件
System.out.println("--- 读取文本文件 ---");
try (BufferedReader reader = new BufferedReader(new FileReader("myTextFile.txt", StandardCharsets.UTF_8))) {
// 同样,这里如果需要严格控制编码,应该用 InputStreamReader
// new BufferedReader(new InputStreamReader(new FileInputStream("myTextFile.txt"), StandardCharsets.UTF_8))
// 不过FileReader(String fileName, Charset charset) 也是Java 11+ 的便利方法
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
System.out.println("文本文件读取完毕。");
} catch (IOException e) {
System.err.println("读取文本文件时发生错误: " + e.getMessage());
}
// 读取二进制文件
System.out.println("\n--- 读取二进制文件 ---");
try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream("myBinaryFile.bin"))) {
int byteRead;
System.out.print("读取到的二进制数据 (十进制): ");
while ((byteRead = bis.read()) != -1) {
System.out.print(byteRead + " ");
}
System.out.println("\n二进制文件读取完毕。");
} catch (IOException e) {
System.err.println("读取二进制文件时发生错误: " + e.getMessage());
}
}
}核心要点:
try-with-resources
try
BufferedInputStream
BufferedOutputStream
BufferedReader
BufferedWriter
FileInputStream
FileOutputStream
FileReader
FileWriter
StandardCharsets.UTF_8
这确实是个好问题,常常让人纠结。简单来说,传统IO(
java.io
java.nio.file
传统IO (java.io
NIO.2 (java.nio.file
Files
java.nio
Path
Path
File
Files
我该如何选择?
这取决于你的具体需求和项目的Java版本。
try-with-resources
WatchService
Files
Files.readAllLines()
Files.writeString()
在我看来,对于现代Java应用开发,NIO.2的
java.nio.file
文件I/O操作是个双刃剑,用不好很容易掉坑里,甚至影响整个应用的性能和稳定性。我个人在处理文件时,踩过不少坑,也总结了一些经验。
常见的陷阱:
不关闭流(Resource Leaks): 这是最最常见的错误!如果文件流没有正确关闭,会导致文件句柄泄露,文件被锁定,无法删除或修改,最终可能耗尽系统资源。
try-with-resources
try
finally
null
try-catch
字符编码问题(乱码): 尤其是在跨平台或处理不同来源的文本文件时,如果读写时使用的编码不一致,就会出现乱码。
StandardCharsets.UTF_8
FileReader
FileWriter
Charset
InputStreamReader
OutputStreamWriter
不使用缓冲流(性能低下): 直接使用
FileInputStream
FileOutputStream
FileReader
FileWriter
BufferedInputStream
BufferedOutputStream
BufferedReader
BufferedWriter
文件路径问题: 相对路径在不同执行环境下可能解析到不同的位置;路径中包含特殊字符(如空格、中文)在某些旧系统或API下可能出问题。
Path
权限不足或文件不存在: 尝试读写一个不存在的文件,或者没有足够权限的文件,会抛出
IOException
FileNotFoundException
AccessDeniedException
Files.exists()
Files.createFile()
IOException
性能优化技巧:
使用缓冲流: (再次强调,因为太重要了)这是最基本也是最有效的优化手段。
// 示例:使用缓冲流复制文件
try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream("source.txt"));
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("destination.txt"))) {
byte[] buffer = new byte[8192]; // 8KB 缓冲区
int bytesRead;
while ((bytesRead = bis.read(buffer)) != -1) {
bos.write(buffer, 0, bytesRead);
}
} catch (IOException e) {
e.printStackTrace();
}利用NIO.2的便利方法: 对于一些常见的读写操作,
Files
Files.readAllBytes(Path path)
Files.readAllLines(Path path, Charset cs)
List<String>
Files.write(Path path, byte[] bytes, OpenOption... options)
Files.writeString(Path path, CharSequence csq, Charset cs, OpenOption... options)
Files.copy(Path source, Path target, CopyOption... options)
内存映射文件(Memory-Mapped Files,NIO MappedByteBuffer
批量写入: 如果你需要写入大量小块数据,尽量将它们聚合成更大的块再写入,而不是每次写入一小部分。例如,在循环中构建一个
StringBuilder
writer.write(stringBuilder.toString())
避免不必要的刷新(flush()
flush()
try-with-resources
flush
Java在文件系统操作方面提供了相当丰富的功能,尤其是在NIO.2(
java.nio.file
文件和目录的创建、删除、移动与复制:
Files.createFile(Path path)
Files.createDirectory(Path dir)
Files.createDirectories(Path dir)
Files.delete(Path path)
Files.deleteIfExists(Path path)
Files.copy(Path source, Path target, CopyOption... options)
StandardCopyOption.REPLACE_EXISTING
StandardCopyOption.COPY_ATTRIBUTES
Files.move(Path source, Path target, CopyOption... options)
StandardCopyOption.ATOMIC_MOVE
文件属性操作:
Files.size(Path path)
Files.getLastModifiedTime(Path path)
Files.readAttributes(Path path, Class<A> type, LinkOption... options)
BasicFileAttributes
DosFileAttributes
PosixFileAttributes
Files.setAttribute(Path path, String attribute, Object value, LinkOption... options)
文件系统遍历和查找:
Files.walk(Path start, int maxDepth, FileVisitOption... options)
Stream<Path>
Files.find(Path start, int maxDepth, BiPredicate<Path, BasicFileAttributes> matcher, FileVisitOption... options)
Files.list(Path dir)
Stream<Path>
临时文件和目录:
Files.createTempFile(String prefix, String suffix, FileAttribute<?>... attrs)
Files.createTempDirectory(String prefix, FileAttribute<?>... attrs)
符号链接和硬链接:
Files.createSymbolicLink(Path link, Path target, FileAttribute<?>... attrs)
Files.createLink(Path link, Path existing)
Files.isSymbolicLink(Path path)
文件系统监控(WatchService
这些高级操作让Java在文件系统层面的控制力大大增强,使得开发者可以编写出更健壮、更灵活的文件处理程序。在我的日常开发中,NIO.2的
Files
Path
以上就是java怎样操作文件进行读写操作 java文件读写的详细操作教程的详细内容,更多请关注php中文网其它相关文章!
java怎么学习?java怎么入门?java在哪学?java怎么学才快?不用担心,这里为大家提供了java速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号