FileChannel
FileChannel 只能工作在阻塞模式下 - 文件处于本地,无需等待
获取
FileChannel 无法直接打开,仅能通过 getChannel()
间接获取
-
通过 FileInputStream 获取的 Channel 只能读
-
通过 FileOutputStream 获取的 Channel 只能写
-
通过 RandomAccessFile 获取的 Channel 能否读写取决于构造时设置的读写模式
写入
正确的姿势如下(事实上 FileChannel 不限制写入,但为了遵循 SocketChannel 写入习惯我们如此进行)
ByteBuffer buffer = ...;
buffer.put(...); // 存入数据
buffer.flip(); // 切换读写模式
while (buffer.hasRemaining()) {
channel.write(buffer); // Channel 有写能力上限
}
关闭
Channel 必须关闭,不过调用 FileInputStream、FileOutputStream、RandomAccessFile 的 close 方法后会间接调用 Channel#close()
两个 CHannel 传输数据
String fromPath = ...;
String toPath = ...;
try (
FileChannel from = new FileInputStream(fromPath).getChannel();
FileChannel to = new FileOutputStream(toPath).getChannel();
) {
long size = from.size();
for (long left = size; left > 0;) {
// 效率高,底层会利用操作系统的零拷贝优化,上限 2G
left -= from.transferTo(size-left, left, to);
}
} catch (IOException e) {
e.printStackTrace();
}
Path
jdk7 引入了 Path 和 Paths 类
-
Path 表示文件路径
-
Paths 用于获取 Path 实例,是工具类
.
代表当前路径
..
代表上一级路径
parent/./son/../son <=> parent/son
Files
常用方法
-
Files#exists(Path)
检查文件是否存在
-
Files#createDirectory(Path)
创建一级目录
-
Files#createDirectories(Path)
创建多级目录
-
Files#copy(Path, Path, (StandardCopyOption))
拷贝文件,如果希望用 source 覆盖 target 则需加上
StandardCopyOption.REPLACE_EXISTING
-
Files#move(Path, Path, (StandardCopyOption))
移动文件。
StandardCopyOption.ATOMIC_MOVE
可以保证文件移动的原子性 -
Files#delete(Path)
删除文件 / 空目录
遍历文件树目录
public static void main(String[] args) throws IOException {
Path path = Paths.get("E:\\JCode\\idea\\study\\netty-baisc\\src");
Files.walkFileTree(path, new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
System.out.println(file.getFileName());
return super.visitFile(file, attrs); // 最好不要变动
}
});
}